在项目开发中出现异常时很平常不过的实现事情,我们处理异常也有很多种方式,可能如下: public int div(int a ,全局int b){ int c=0; try{ c=a/b; }catch (Exception ex){ ex.printStackTrace(); } return c; 如果我们这样处理异常,代码中就会出现特别多的异常处理模块,这样代码就会变得可读性非常差,异常而且业务模块逻辑会夹杂特别多的处理非业务逻辑。但是总结在项目开发的过程中我们应该将主要精力放在业务模块,除了必要的实现异常处理模块最好不要再包含其他无关紧要的代码。那么我们如何处理项目中无处不在的全局异常呢?这就引出了我们要介绍的全局异常处理方法,主要有两种种方式: 首先我们先介绍一下@ControllerAdvice和@ExceptionHandler @ControllerAdvice+@ExceptionHandler只要设计得当,实现就不用再在Controller使用trg-catch了!下面我们先写介绍一个Controller层全局异常处理类。 @ControllerAdvice public class GlobalExceptionHandler { @ResponseBody @ExceptionHandler(Exception.class) public CommonResult exceptionHandler(HttpServletRequest request,全局 Exception exception) throws Exception { Map String message =exception.getMessage()+request.getRequestURL().toString(); return CommonResult.failed(message); } 注:@ResponseBody的作用其实是将java对象转为json格式的数据。然后到这里为止,异常一个简单的处理全局异常处理解决方式就完成了,这只是一个简单的异常处理方式,远远不能达到完整项目中全局异常处理的总结方案。 我们项目中业务处理,可以通过自定义的异常知道哪一个模块发生异常,并且不同的业务模块也有不同的异常处理方式,源码库这也方便我们做扩展 public class ServiceException extends RuntimeException { private IErrorCode errorCode; public ServiceException(IErrorCode errorCode) { super(errorCode.getMessage()); this.errorCode = errorCode; } public ServiceException(String message) { super(message); } public ServiceException(Throwable cause) { super(cause); } public ServiceException(String message, Throwable cause) { super(message, cause); } public IErrorCode getErrorCode() { return errorCode; } }加入自定义异常处理@ControllerAdvice public class GlobalExceptionHandler { / * 处理所有Service层异常 */ @ResponseBody @ExceptionHandler(value = ServiceException.class) public CommonResult handle(ServiceException e) { if (e.getErrorCode() != null) { return CommonResult.failed(e.getErrorCode()); } return CommonResult.failed(e.getMessage()); } / * 处理所有不可知的异常 */ @ResponseBody @ExceptionHandler(Exception.class) public CommonResult exceptionHandler(HttpServletRequest request, Exception exception) throws Exception { Map String message =exception.getMessage()+request.getRequestURL().toString(); return CommonResult.failed(message); } 在用户登录Model字段上注解数据校验规则。 @Data @EqualsAndHashCode(callSuper = false) public class UserLoginParam { @NotEmpty private String username; @NotEmpty private String password; SpringBoot中可以使用@Validated + @RequestBody注解方式实现数据绑定和数据校验。例如登录方式为: @ApiOperation(value = "登录以后返回token") @RequestMapping(value = "/login", method = RequestMethod.POST) @ResponseBody public CommonResult login(@Validated @RequestBody UmsAdminLoginParam umsAdminLoginParam) { String token = adminService.login(umsAdminLoginParam.getUsername(), umsAdminLoginParam.getPassword()); if (token == null) { return CommonResult.validateFailed("用户名或密码错误"); } Map tokenMap.put("token", token); tokenMap.put("tokenHead", tokenHead); return CommonResult.success(tokenMap); 如果数据校验不对数据抛出的异常为MethodArgumentNotValidException,所以我们可以在全局异常处理类中添加对MethodArgumentNotValidException异常的处理声明,就可以实现全局处理数据校验和绑定的异常了,实现如下: @ResponseBody @ExceptionHandler(value = MethodArgumentNotValidException.class) public CommonResult handleValidException(MethodArgumentNotValidException e) { BindingResult bindingResult = e.getBindingResult(); String message = null; if (bindingResult.hasErrors()) { FieldError fieldError = bindingResult.getFieldError(); if (fieldError != null) { message = fieldError.getField()+fieldError.getDefaultMessage(); } } return CommonResult.validateFailed(message); 通过上面介绍的未知异常、数据校验和自定义全局异常所有的Controller层的异常处理方式全部都集中到了GlobalExceptionHandler类中,那么我们在Controller类中就不再需要收到记录错误了。 GlobalExceptionHandler全部代码@ControllerAdvice public class GlobalExceptionHandler { @ResponseBody @ExceptionHandler(value = ApiException.class) public CommonResult handle(ApiException e) { if (e.getErrorCode() != null) { return CommonResult.failed(e.getErrorCode()); } return CommonResult.failed(e.getMessage()); } @ResponseBody @ExceptionHandler(Exception.class) public CommonResult exceptionHandler(HttpServletRequest request, Exception exception) throws Exception { Map String message =exception.getMessage()+request.getRequestURL().toString(); return CommonResult.failed(message); // return result; } @ResponseBody @ExceptionHandler(value = MethodArgumentNotValidException.class) public CommonResult handleValidException(MethodArgumentNotValidException e) { BindingResult bindingResult = e.getBindingResult(); String message = null; if (bindingResult.hasErrors()) { FieldError fieldError = bindingResult.getFieldError(); if (fieldError != null) { message = fieldError.getField()+fieldError.getDefaultMessage(); } } return CommonResult.validateFailed(message); } 今天主要讲解了@ControllerAdvice+@ExceptionHandler进行统一的在Controller层上的全局异常处理。SpringBoot实现全局异常处理