SpringBoot实现全局异常处理总结

SpringBoot实现全局异常处理

  public int div(int a ,int b){
int c=0;
try{
c=a/b;
}catch (Exception ex){
ex.printStackTrace();
}
return c;
}

如果我们这样处理异常,代码中就会出现特别多的异常处理模块,这样代码就会变得可读性非常差,而且业务模块逻辑会夹杂特别多的非业务逻辑。但是在项目开发的过程中我们应该将主要精力放在业务模块,除了必要的异常处理模块最好不要再包含其他无关紧要的代码。那么我们如何处理项目中无处不在的异常呢?这就引出了我们要介绍的全局异常处理方法,主要有两种种方式:

站在用户的角度思考问题,与客户深入沟通,找到波密网站设计与波密网站推广的解决方案,凭借多年的经验,让设计与互联网技术结合,创造个性化、用户体验好的作品,建站类型包括:成都做网站、网站制作、企业官网、英文网站、手机端网站、网站推广、国际域名空间、雅安服务器托管、企业邮箱。业务覆盖波密地区。

  • HandlerExceptionResolver。
  • @ControllerAdvice+@ExceptionHandler 今天我们主要介绍一下@ControllerAdvice+@ExceptionHandler模式处理全局异常。

全局异常处理

首先我们先介绍一下@ControllerAdvice和@ExceptionHandler

  • @ControllerAdvice注解:他是一个比较特殊的@Component,用于定义全局异常处理类作用在所有的@Controller类型的接口上。
  • @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 result = new HashMap<>(3);
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 result = new HashMap<>(3);
String message =exception.getMessage()+request.getRequestURL().toString();
return CommonResult.failed(message);
}

}

处理 Controller 数据绑定、数据校验的异常

在用户登录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 = new HashMap<>();
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 result = new HashMap<>(3);
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实现全局异常处理总结
文章地址:http://www.shufengxianlan.com/qtweb/news8/298558.html

网站建设、网络推广公司-创新互联,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联