阿华代码,不是逆风,就是我疯
你们的点赞收藏是我前进最大的动力!!
希望本文内容能够帮助到你!!
目录
一:登录模块设计
1:实体类
2:登录的请求和响应设计
二:设计统一的响应体类
1:参考
(1)@ControllerAdvice
(2)ResponseBodyAdvice接口
2:自己设计统一结果响应类
三:用户登录管理类
1:@RestController
2:代码理解
四:UserMapper层
1:设计接口
2:配置UserMapper.xml
一:登录模块设计
1:实体类
@Data
public class Music {private int id;private String title;private String singer;private String url;private String time;private int userid;
}
@Data
public class User {private Integer id;private String userName;private String password;
}
2:登录的请求和响应设计
二:设计统一的响应体类
1:参考
因为在博客系统项目中,已经使用过统一结果返回了,如下
注解介绍
(1)@ControllerAdvice
全局响应处理,它可以拦截所有被@Controller和@RestController注解修饰的类里的方法(后面为方便描述统一叫Controller方法了哈)。他就是一个增强类
就好比,无论你是谁,你进火车站都得过安检,
(2)ResponseBodyAdvice接口
用于在Controller方法返回我们包装的响应体之前,对响应(body)做处理。
注意:这个接口中同一结果返回已经包含了序列化,所以我们要对String类型单独做处理,避免统一结果返回的时候双重序列化!!解决办法就是提前先给序列化
看这个例子——Jackson库中ObjectMapper类序列化操作
第一步:把String类包装为Result对象
第二步:再把这个对象序列化为字符串
if(body instanceof String){return objectMapper.writeValueAsString(Result.success(body));}
拉回来:ResponseBodyAdvice需要实现两个方法
①supports()
类似启动开关,true为开,判断是否需要对当前返回值进行处理
②beforeBodyWrite()
在返回响应体之前对数据进行处理。这里主要是类型的判定
这里,我想尝试自己去模拟ResponseAdvice设计一个类,用作统一结果返回
2:自己设计统一结果响应类
女少!~
@Data
public class ResponseBodyMessage <T>{private int status;//返回状态码private String message;private T data;//返回数据public ResponseBodyMessage(int status, String message, T data) {this.status = status;this.message = message;this.data = data;}
}
三:用户登录管理类
1:@RestController
两个注解组成@Controller+@ResponseBody
被@RestController修饰的类,会被我们的启动类扫描到,主要处理HTTP请求
只有@Controller修饰,返回的是视图
加上@ResponseBody,就是告诉Spring我要直接将对象写入请求体当中,不要视图解析器解析我
简记:一个返回视图,一个返回具体数值
其它几个依赖注入,路由映射,参数绑定就不多bb了~~
2:代码理解
这里我们拿到前端输入的用户名和密码后,跟数据库中的数据进行比对校验
这里重点讲一下Cookie和Session会话,密码校验成功,服务器在响应体的Set-Cookie字段中添加一个令牌,这个令牌是服务器随机给的,比如说现在是:会话一,里面是一个key-value结构
Constants.USERINFO_SESSION_KEY就对应key,用户信息就对应value
public class Constants {public static final String USERINFO_SESSION_KEY = "USERINFO_SESSION_KEY";
}
这里的加密解析算法,先埋个伏笔,下一篇文章将详细解释
@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate UserService userService;@Autowiredprivate BCryptPasswordEncoder bCryptPasswordEncoder;@RequestMapping("/login")public ResponseBodyMessage<User> login(@RequestParam String userName, @RequestParam String password , HttpServletRequest request){User loginUser = new User();loginUser.setUserName(userName);loginUser.setPassword(password);User userInfo = userService.selectByName(loginUser);if(userInfo == null){return new ResponseBodyMessage<>(-1,"用户名或者密码错误", userInfo);}else{if(!bCryptPasswordEncoder.matches(password,userInfo.getPassword())){return new ResponseBodyMessage<>(-1,"用户名或者密码错误",userInfo);}request.getSession().setAttribute(Constants.USERINFO_SESSION_KEY, userInfo);return new ResponseBodyMessage<>(0,"登录成功", userInfo);}}}
四:UserMapper层
1:设计接口
@Mapper
public interface UserMapper {User login(User loginUser);//username⽤⼾名是唯⼀的User selectByName(String username);}
2:配置UserMapper.xml
在resource⽬录下,新建mybatis⽂件夹,新建UserMapper.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd">
<mapper namespace="com.example.musicserver.mapper.UserMapper"><select id="login" resultType="com.example.musicserver.model.User">select id , username , password from user where username = #{userName} and password = #{password}</select><select id="selectByName" resultType="com.example.musicserver.model.User">select id , username , password from user where username = #{userName}</select>
</mapper>