一、统一用户登录权限验证
1.1Spring拦截器
实现拦截器需要以下两步:
1.创建自定义拦截器,实现 HandlerInterceptor 接口的 preHandle(执行具体方法之前的预处理)方法。
2.将自定义拦截器加⼊ WebMvcConfigurer 的 addInterceptors 方法中
1.1.1自定义拦截器
package com.example.demo.interceptor;
import org.springframework.web.servlet.HandlerInterceptor;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
/**
* 创建一个登录的拦截器
*/
public class LoginInterceptor implements HandlerInterceptor {
//返回true表示验证通过,可以执行后面的方法;
// 但是返回false表示验证失败,后面的代码就不能执行了
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session = request.getSession(false);
if (session != null && session.getAttribute("userinfo") != null){
//表明用户已登录
return true;
}
//执行到此行,表明验证未通过,自动跳转到登录页面
response.sendRedirect("/login.html");
return false;
}
}
1.1.2将拦截器配置给当前项目
并设置相应的拦截规则
package com.example.demo.config;
import com.example.demo.interceptor.LoginInterceptor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
@Configuration
public class AppConfig implements WebMvcConfigurer {
@Autowired
private LoginInterceptor loginInterceptor;
/**
* 给当前项目添加拦截器
* @param registry
*/
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor)
.addPathPatterns("/**")//拦截使用的url
.excludePathPatterns("/user/reg")//不拦截/user/reg
.excludePathPatterns("/**/*.html");//拦截/**/*.html
}
}
package com.example.demo.controller;
import com.example.demo.model.UserInfo;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
@RestController
@RequestMapping("/user")
public class UserController {
/**
* 注册功能
* @param userInfo
* @return
*/
@RequestMapping("/reg")
public boolean reg(UserInfo userInfo){
//伪代码
return true;
}
/**
* 上传头像
* @return
*/
@RequestMapping("/upload")
public UserInfo upload(){
UserInfo userInfo = new UserInfo();
userInfo.setId(1);
userInfo.setUsername("张三");
userInfo.setPassword("");
return userInfo;
}
/**
* 登录功能
* @param username
* @param password
* @param request
* @return
*/
public boolean login(String username, String password, HttpServletRequest request){
//1.非空校验
if(StringUtils.hasLength(username) && StringUtils.hasLength(password)){
if(username.equals("admin") && password.equals("admin")){
//用户名和密码成功
//添加session
HttpSession session = request.getSession(true);
session.setAttribute("userinfo",new UserInfo(1,"admin","admin"));
return true;
}
}
return false;
}
}
1.2拦截器实现原理
二、统一异常处理
使用 @ControllerAdvice + @ExceptionHandler来实现
@ControllerAdvice:控制器通知类
@ExceptionHandler:异常处理器
结合表示当出现异常的时候执行某个通知。
2.1创建异常类
添加@ControllerAdvice 注解
2.2实现异常的封装方法
添加@ExceptionHandler注解
package com.example.demo.config;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;
import java.util.HashMap;
@ControllerAdvice//对控制器进行功能增强(当前类为统一封装类)
public class MyExceptionResult {
@ResponseBody
@ExceptionHandler(Exception.class)
public HashMap<String,Object> myException(Exception e){
HashMap<String,Object> result = new HashMap<String,Object>();
result.put("state",-1);
result.put("msg","默认异常"+e.getMessage());
result.put("data",null);
return result;
}
}
三、统一数据格式返回
以使用@ControllerAdvice + ResponseBodyAdvice实现
package com.example.demo.config;
import org.springframework.core.MethodParameter;
import org.springframework.http.MediaType;
import org.springframework.http.server.ServerHttpRequest;
import org.springframework.http.server.ServerHttpResponse;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.servlet.mvc.method.annotation.ResponseBodyAdvice;
import java.util.HashMap;
@ControllerAdvice
public class MyResponseBodyAdvice implements ResponseBodyAdvice {
//是否要重写的方法改为true,true表示在返回数据之前,进行统一的格式封装
@Override
public boolean supports(MethodParameter returnType, Class converterType) {
return true;
}
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
HashMap<String,Object> result = new HashMap<>();
result.put("state",1);
result.put("data",body);
result.put("msg","");
return result;
}
}