1. 拦截器
1.1 拦截器快速入门
拦截器用于拦截用户请求,执行在目标方法前后,执行了一段代码
拦截器使用:
- 定义拦截器
- 注册并配置拦截器
自定义拦截器,实现HandlerInterceptor接口,并重写所有方法
//拦截器 @Slf4j public class LoginInterceptor implements HandlerInterceptor { @Override public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception { log.info("目标方法执行前执行"); //true=>放行 false=>拦截 return true; } @Override public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception { log.info("目标方法执行后执行"); } @Override public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception { log.info("页面渲染后执行"); } }
配置拦截器,实现WebMvcConfigurer 接口 ,并重写addInterceptors方法
@Configuration public class WebConfig implements WebMvcConfigurer { @Autowired private LoginInterceptor loginInterceptor;//注入上面设置的拦截器 //重写方法 @Override public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(loginInterceptor) .addPathPatterns("/**") .excludePathPatterns("/static/css/**", "/static/js/**", "/static/pic/**", "/user/login"); }
}
1.2 拦截器详解
1.2.1 拦截路径
- /**:匹配所有路径
- /admin/*:匹配/admin下的单级路径
- /admin/**:匹配/admin下的多级路径
1.2.2 拦截器执行流程
客户端请求
↓
preHandle()方法
↓ 返回true
处理器方法执行
↓
postHandle()方法
↓
视图渲染
↓
afterCompletion()方法
2. 统一数据返回格式
创建统一响应体类:
package com.example.springbookdemo.entity; import com.example.springbookdemo.enums.ResultCodeEnum; import lombok.Data; @Data public class Result<T> { private int code;//-1=>未登录 -2=>参数错误 200=>正常 -100=>异常 private String message; private T data; public static <T> Result<T> unLogin(){ Result<T> result=new Result<T>(); result.setCode(ResultCodeEnum.UNLOGIN.getCode()); result.setMessage(ResultCodeEnum.UNLOGIN.getMessage()); return result; } public static <T> Result<T> success(T data){ Result<T> result=new Result<T>(); result.setCode(ResultCodeEnum.SUCCESS.getCode()); result.setMessage(""); result.setData(data); return result; } public static <T> Result<T> pararmError (){ Result<T> result=new Result<T>(); result.setCode(ResultCodeEnum.PARARM_ERROR.getCode()); result.setMessage(ResultCodeEnum.PARARM_ERROR.getMessage()); return result; } public static <T> Result<T> pararmError (String message){ Result<T> result=new Result<T>(); result.setCode(ResultCodeEnum.PARARM_ERROR.getCode()); result.setMessage(message); return result; } public static <T> Result<T> Fail (String message){ Result<T> result=new Result<T>(); result.setCode(ResultCodeEnum.FAIL.getCode()); result.setMessage(message); return result; } }
编写一个类实现ResponseBodyAdvice接口,并重写两个方法,添加 @ControllerAdvice
@ControllerAdvice public class ResponseAdvice implements ResponseBodyAdvice { @Override public boolean supports(MethodParameter returnType, Class converterType) { //该方法用于判断是否对结果进行处理 //true为处理,false为不处理 return true; } @Autowired ObjectMapper objectMapper;//便于后续对String转JSon操作 @SneakyThrows//相当于使用try/catch //上一个方法返回true则执行该方法 @Override public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) { //该方法用于处理结果 //参数中的body代表结果 if(body instanceof Result){ return body; } //统一结果返回,需要额外对String类型进行处理 if(body instanceof String){ return objectMapper.writeValueAsString(Result.success(body)); //返回JSON } return Result.success(body); } }
3. 统一异常处理
用@ControllerAdvice+@ExceptionHandler实现
//统一异常处理 @ControllerAdvice @ResponseBody public class ErrorAdvice { @ExceptionHandler public Object handler(Exception e){ return Result.Fail(e.getMessage()); } }