全局异常处理的好处:不用逐个方法手动try-catch异常,提高开发效率,降低代码冗余
思路:@ControllerAdvice + @ExceptionHandler
@ExceptionHandler 注解用于拦截异常,可以通过该注解实现自定义异常处理。其中,@ExceptionHandler 配置的 value 指定需要拦截的异常类型。
@ExceptionHandler(value = SaTokenException.class)
@ControllerAdvice 注解用于定义@ExceptionHandler,并应用到所有@RequestMapping中。
如果全部异常处理返回json,那么可以使用 @RestControllerAdvice 代替 @ControllerAdvice ,这样在方法上就可以不需要添加 @ResponseBody。
下面使用@RestControllerAdvice和@ExceptionHandler展示全局异常处理的demo。
1. 编写全局异常处理类
package com.cjl.mss.common.exception;
@RestControllerAdvice
public class GlobalExceptionResolver{
@ExceptionHandler(SaTokenException.class)
public Object handleAuthorizationException(HttpServletRequest request, SaTokenException e)
{
// 登录认证异常
if(e instanceof NotLoginException){
return ResponseEntity.status(HttpStatus.UNAUTHORIZED).body(e.getMessage());
}
// 权限认证异常
else if (e instanceof NotPermissionException || e instanceof NotRoleException || e instanceof NotSafeException){
return ResponseEntity.status(HttpStatus.FORBIDDEN).body(e.getMessage());
}
// 其它异常
else {
return ResponseEntity.status(HttpStatus.FORBIDDEN).body("oops, error!");
}
}
/**
* 请求方式不支持
*/
@ExceptionHandler({ HttpRequestMethodNotSupportedException.class })
public ResponseEntity<String> handleException(HttpRequestMethodNotSupportedException e)
{
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("不支持' " + e.getMethod() + "'请求");
}
/**
* 系统异常
*/
@ExceptionHandler(Exception.class)
public ResponseEntity<String> handle(Exception e){
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("系统异常:" + e.getMessage());
}
/**
* 拦截未知的运行时异常
*/
@ExceptionHandler(RuntimeException.class)
public ResponseEntity<String> notFount(RuntimeException e)
{
return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("运行时异常:" + e.getMessage());
}
}
2. 注入Spring容器
package com.cjl.mss.auth;
@ComponentScan({"com.cjl.mss.auth", "com.cjl.mss.common"})
@SpringBootApplication(exclude= {DataSourceAutoConfiguration.class})
public class MSSAuthApplication {
public static void main(String[] args) {
SpringApplication.run(MSSAuthApplication.class,args);
}
}
3. 补充
- 若全局异常处理类和SpringBoot启动类在同一个包下,则无需使用@ComponentScan注解。
- ResponseEntity对象是Spring对请求响应的封装。它继承了HttpEntity对象,包含了Http的响应码(httpstatus)、响应头(header)、响应体(body)三个部分。可以根据业务需要自定义返回实体。
- 可以自定义异常类,实现更贴合业务的异常拦截。