拦截器
拦截器是Spring框架提供的核心功能之⼀,主要用来拦截用户的请求,在指定方法前后,根据业务需要执行预先设定的代码,例如强制登录功能。
拦截器的使用分为定义拦截器和配置拦截器两部分
定义
java
@Component
@Slf4j
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
HttpSession session =request.getSession();
log.info("请求前");
UserInfo userInfo = (UserInfo) session.getAttribute(Constants.USER_SESSION_KEY);
if(userInfo == null || userInfo.getId()<=0) {
response.setStatus(401);
return false;
}
return true;
}
@Override
public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {
HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
log.info("请求后");
}
@Override
public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
log.info("视图渲染后");
}
}
注册
java
@Configuration
public class WebConfig implements WebMvcConfigurer {
@Autowired
private LoginInterceptor loginInterceptor;
@Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(loginInterceptor)
.addPathPatterns("/**")
.excludePathPatterns("/user/login")
.excludePathPatterns("/css/**")
.excludePathPatterns("/js/**")
.excludePathPatterns("/pic/**")
.excludePathPatterns("/**/*.html")
;
}
}
拦截器执行流程


统一数据返回格式
代码
java
@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {
private static ObjectMapper mapper = new ObjectMapper();
@Override
public boolean supports(MethodParameter returnType, Class converterType) {
return true;
}
@SneakyThrows
@Override
public Object beforeBodyWrite(Object body, MethodParameter returnType, MediaType selectedContentType, Class selectedConverterType, ServerHttpRequest request, ServerHttpResponse response) {
if (body instanceof String){
return mapper.writeValueAsString(Result.success(body));
}
return Result.success(body);
}
}
其中对于String类型要进行特殊处理的原因是,Spring对于一般对象和String类型使用的处理器不同,其他对象使用的处理器,会自己转换为json字符串,而String类型会直接写入结构体中,因此需要进行特殊转换。
对于本身为Result类型的对象,直接返回body即可,要不会套两层。因为我代码中不存在,所以我没写。
统一异常处理
代码
java
@Slf4j
@ResponseBody
@ControllerAdvice
public class ExceptionAdvice {
@ExceptionHandler
public Result handlerException(Exception e){
log.error("发生异常, e: {}", e);
return Result.fail("内部错误");
}
@ExceptionHandler
public Result handlerException(NullPointerException e){
log.error("发生异常, e:", e);
return Result.fail("发生空指针异常");
}
@ExceptionHandler
public Result handlerException(ArithmeticException e){
log.error("发生异常, e:", e);
return Result.fail("发生算术异常");
}
}