@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;
}
因为在博客系统项目中,已经使用过统一结果返回了,如下
注解介绍
全局响应处理,它可以拦截所有被@Controller和@RestController注解修饰的类里的方法(后面为方便描述统一叫Controller方法了哈)。他就是一个增强类
就好比,无论你是谁,你进火车站都得过安检,
用于在Controller方法返回我们包装的响应体之前,对响应(body)做处理。
注意:这个接口中同一结果返回已经包含了序列化,所以我们要对String类型单独做处理,避免统一结果返回的时候双重序列化!!解决办法就是提前先给序列化
看这个例子——Jackson库中ObjectMapper类序列化操作
第一步:把String类包装为Result对象
第二步:再把这个对象序列化为字符串
if(body instanceof String){
return objectMapper.writeValueAsString(Result.success(body));
}
拉回来:ResponseBodyAdvice需要实现两个方法
①supports()
类似启动开关,true为开,判断是否需要对当前返回值进行处理
②beforeBodyWrite()
在返回响应体之前对数据进行处理。这里主要是类型的判定
这里,我想尝试自己去模拟ResponseAdvice设计一个类,用作统一结果返回
女少!~
@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;
}
}
两个注解组成@Controller+@ResponseBody
被@RestController修饰的类,会被我们的启动类扫描到,主要处理HTTP请求
只有@Controller修饰,返回的是视图
加上@ResponseBody,就是告诉Spring我要直接将对象写入请求体当中,不要视图解析器解析我
简记:一个返回视图,一个返回具体数值
其它几个依赖注入,路由映射,参数绑定就不多bb了~~
这里我们拿到前端输入的用户名和密码后,跟数据库中的数据进行比对校验
这里重点讲一下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 {
@Autowired
private UserService userService;
@Autowired
private 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);
}
}
}
@Mapper
public interface UserMapper {
User login(User loginUser);
//username⽤⼾名是唯⼀的
User selectByName(String username);
}
在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>