由于之前那篇文章是在大学期间好多东西都不太懂的时候写的,放到现在再来看总感觉到处都是问题(或者说已经看不懂啦)。但是看到每天上涨的那点阅读量,想了想还是把这个再用相对正常的方式再重写一遍吧。

为了省事本项目的服务端采用SpringBoot + MybatisPlus开发,要是Java水平还不够的小伙伴就自己再稍微努力努力 (°∀°)ノ

一、服务端

首先对SpringBoot提一嘴,这玩意是用来简化Spring应用的初始搭建以及开发过程的。

创建好工程之后在pom文件中导入相关依赖,用到的大概有mysql、druid、mybatis。mybatis-plus、fastjson、lombok等。

随后对配置信息进行设置,这里采用yml文件的格式。

server:

port: 80

spring:

#数据库相关配置

datasource:

driver-class-name: com.mysql.cj.jdbc.Driver

url: jdbc:mysql://localhost:3306/db1?serverTimezone=UTC

username: root

password: 1234

#设置数据源为druid

type: com.alibaba.druid.pool.DruidDataSource

cache:

redis:

time-to-live: 1800000

mybatis-plus:

global-config:

db-config:

id-type: assign_id

configuration:

#在映射实体或者属性时,将数据库中表名和字段名中的下划线去掉,按照驼峰命名法映射

map-underscore-to-camel-case: true

log-impl: org.apache.ibatis.logging.stdout.StdOutImpl

随后就是紧张刺激(并不)的代码开发啦。

由于本项目只是为了实现Android访问MySQL数据库,就只是模拟实现了一个用户登录功能。

先准备好MySQL中的数据:

对应好实体类中的User类:

@Data

public class User {

private Integer id;

private String userId;

private String userName;

private String password;

private String phoneNumber;

private String sex;

private String personalSignature;

}

由于使用了MybatisPlus,所以数据层会显的非常简单:

@Mapper

public interface UserMapper extends BaseMapper {

}

业务层接口:

public interface UserService extends IService {

Result login(String userId, String password);

}

业务层实现:

@Service

public class UserServiceImpl extends ServiceImpl implements UserService {

@Autowired

private UserMapper userMapper;

@Override

public Result login(String userId, String password) {

// 1、校验参数

if (StringUtils.isBlank(userId) || StringUtils.isBlank(password)) {

return Result.error("请输入账号和密码");

}

// 2、构造查询条件

LambdaQueryWrapper queryWrapper = new LambdaQueryWrapper<>();

queryWrapper.eq(User::getUserId, userId);

queryWrapper.eq(User::getPassword, password);

User user = userMapper.selectOne(queryWrapper);

// 3、判断查询结果

if (user != null) {

return Result.success(user);

} else {

return Result.error("账号或密码错误");

}

}

}

表现层:

@Slf4j

@RestController

@RequestMapping("/user")

public class UserController {

@Autowired

private UserService userService;

@PostMapping("/login")

public Result login(@RequestBody Map userInfo) {

log.info("用户登录");

String userId = userInfo.get("userId");

String password = userInfo.get("password");

return userService.login(userId, password);

}

}

其中的Result为通用的返回结果类,包含了状态码、错误信息以及返回数据等内容。

至此,服务端的开发就告一段落。运行启动类,进行调试。

二、Android端

创建完工程后简单的写两个页面,一个用于登录,一个用于展示信息。

对页面控件进行初始化完成后,给按钮添加一个点击事件:

btn_login.setOnClickListener(v -> {

String id = et_id.getText().toString();

String pwd = et_pwd.getText().toString();

// 判断用户输入账号和密码是否为空

if (StringUtil.isNotEmpty(id) && StringUtil.isNotEmpty(pwd)){

loginTest(id, pwd);

}else {

ToastUtil.showShort( LoginActivity.this, "请输入账号和密码");

}

});

具体实现思路是:使用OkHttp向服务端发送请求,将服务端返回的JSON数据用GSON进行解析,从而将在数据库中获取到的信息进行展示。具体实现如下:

private void loginTest(String id, String pwd) {

new Thread(() -> {

try {

// 创建OKHttp客户端

OkHttpClient client = new OkHttpClient();

// 构造消息体(不是JSON格式)

RequestBody requestBody = new FormBody.Builder()

.add("userId", id)

.add("password", pwd)

.build();

// 发送post请求

Request request = new Request.Builder()

.url("http://server.natappfree.cc:39945/user/login")

.post(requestBody)

.build();

// 获取响应

Response response = client.newCall(request).execute();

String userInfo = response.body().string();

// 利用GSON将返回的JSON格式数据转化为对象

Gson gson = new Gson();

Result result = gson.fromJson(userInfo, Result.class);

// 判断返回结果,确认登录是否成功

if (result == null) {

ToastUtil.showShortInThread(LoginActivity.this, "登录失败");

return;

}

if (result.getCode() == 1 && result.getData() != null) {

String userStr = result.getData().toString();

User user = gson.fromJson(userStr, User.class);

Intent intent = new Intent(LoginActivity.this, UserInfoActivity.class);

intent.putExtra("User", user);

startActivity(intent);

} else {

ToastUtil.showShortInThread(LoginActivity.this, result.getMsg());

return;

}

} catch (Exception e) {

e.printStackTrace();

}

}).start();

}

其中的请求地址使用了NATAPP内网穿透工具将本地的端口进行映射,使得外网也可以访问。(免费隧道每次启动时地址会发生变化)

启动项目:

登录页面

输入正确的账号密码信息,点击登录,并没有反应。检查服务器后发现报了一个异常:

2023-02-22 17:42:58.922  WARN 9424 --- [p-nio-80-exec-5] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpMediaTypeNotSupportedException: Content type 'application/x-www-form-urlencoded;charset=UTF-8' not supported]

经排查发现,在服务端接收参数时使用了@RequestBody注解,表示我们接收的是一个JSON格式的数据,但是OkHttp发送的数据并不是JSON数据,因此在这里报了异常。那么只要在接收参数时直接用两个变量接收即可解决这个问题,修改UserController中的代码:

@PostMapping("/login")

public Result login(String userId, String password) {

log.info("用户登录");

return userService.login(userId, password);

}

重启服务,后再次尝试登陆:

访问成功,撒花✿ヽ(°▽°)ノ✿

 

查看原文