【JavaEE】Spring(7):统一功能处理
一、拦截器
拦截器的使用步骤:
- 定义拦截器
- 注册配置拦截器
1. 定义拦截器
@Slf4j
@Component
public class LoginInterceptor implements HandlerInterceptor {
@Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
log.info("目标方法执行前执行");
return true;
}
preHandle是HandlerInterceptor接口提供的方法,该方法用来判断目标方法执行前是否要拦截,返回true就不拦截,即目标方法可以执行,返回false就拦截,即目标方法禁止执行
2. 配置注册拦截器
@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")
.excludePathPatterns("/test/**")
;
}
}
二、统一数据返回格式
在进行项目开发时,我们通常将后端返回给前端的数据做一个包装,使得让返回的数据格式都相同
@Data
public class Result<T> {
private ResultCodeEnum code;
private String errMsg;
private T data; //包装前,接口返回的数据
}
那么如何将数据进行包装:
@ControllerAdvice
public class ResponseAdvice implements ResponseBodyAdvice {
@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) {
return Result.success(body);
}
}
当一个Controller方法返回一个值时,该值会作为参数传递给supports方法;在supports方法中,通过我们自己编写的逻辑来判断是否需要对返回值进行处理,如果返回true,则将返回值传递给beforeBodyWrite方法,在beforeBodyWrite方法中对返回值进行处理,将处理后的格式作为响应发送给客户端
返回false就不执行beforeBodyWrite方法,即不对返回值进行处理,直接作为响应发送给客户端
三、统一异常处理
统一异常处理通过@ControllerAdvice + @ExceptionHandler 来实现
@ControllerAdvice
@ResponseBody
public class ErrorAdvice {
@ExceptionHandler
public Object handler(Exception e) {
return Result.fail(e.getMessage());
}
}
上述代码表示,如果代码中出现Exception异常(包括Exception子类),就返回一个Result对象,Result.fail(e.getMessage());方法实现如下:
public static <T> Result<T> fail(String errMsg){
Result result = new Result<>();
result.setErrMsg(errMsg);
result.setCode(ResultCodeEnum.FAIL);
result.setData(null);
return result;
}
将Result对象转换为Json格式后返回给前端
如果想要针对不同的异常返回不同的结果,可以这么写:
@RestControllerAdvice //相当于@ResponseBody + @ControllerAdvice
public class ErrorAdvice {
@ExceptionHandler(ArithmeticException.class) //针对算数异常
public Result handler1(Exception e){
log.error("发生ArithmeticException, e:", e);
return Result.fail("发生算术异常: "+e.getMessage());
}
@ExceptionHandler(NullPointerException.class) //针对空指针异常
public Result handler2(Exception e){
log.error("发生NullPointerException, e:", e);
return Result.fail("发生空指针异常: "+e.getMessage());
}
@ExceptionHandler(Exception.class)
public Result handler3(Exception e){
log.error("发生异常, e:", e);
return Result.fail("发生异常: "+ e.getMessage());
}
}
接下来模拟几个异常:
@RequestMapping("/test")
@RestController
public class TestController {
@RequestMapping("/t1")
public String t1(){
int[] arr = {1,2,3};
System.out.println(arr[5]);
return "t1";
}
@RequestMapping("/t2")
public Integer t2(){
int a = 10/0;
return 10;
}
@RequestMapping("/t3")
public Boolean t3(){
String a = null;
System.out.println(a.length());
return true;
}
}
http://127.0.0.1:8080/test/t1:
http://127.0.0.1:8080/test/t2:
http://127.0.0.1:8080/test/t3:
🙉本篇文章到此结束