Spring Boot实战之全局异常捕获 实现参数异常检查返回统一错误信息

转载地址:https://blog.csdn.net/sun_t89/article/details/52057014

转载于这篇,写的很详细,完美的解决了我的问题。详细内容请看原文

在一个项目中的异常我们我们都会统一进行处理的,本文实现对接口中传入的参数进行非法性检查,当参数非法时,抛出异常,然后返回统一的错误信息。

1、添加测试Bean,测试类中定义几个字段,并且每个字段都做一定的限制

  1.  
    package com.xiaofangtech.sunt.bean;
  2.  
     
  3.  
    import javax.validation.constraints.AssertFalse;
  4.  
    import javax.validation.constraints.Size;
  5.  
     
  6.  
    import org.hibernate.validator.constraints.Range;
  7.  
     
  8.  
    public class BeanValidation {
  9.  
    @Size(min=6,max=10)
  10.  
    private String field1;
  11.  
    @Range(min=0,max=1)
  12.  
    private Long field2;
  13.  
    @AssertFalse
  14.  
    private Boolean field3;
  15.  
    public String getField1() {
  16.  
    return field1;
  17.  
    }
  18.  
    public void setField1(String field1) {
  19.  
    this.field1 = field1;
  20.  
    }
  21.  
    public Long getField2() {
  22.  
    return field2;
  23.  
    }
  24.  
    public void setField2(Long field2) {
  25.  
    this.field2 = field2;
  26.  
    }
  27.  
    public Boolean getField3() {
  28.  
    return field3;
  29.  
    }
  30.  
    public void setField3(Boolean field3) {
  31.  
    this.field3 = field3;
  32.  
    }
  33.  
     
  34.  
    }

2、添加测试接口,接口中使用@Validated注解对参数进行合法性检查,如果参数合法,返回原始数据

  1.  
    @RequestMapping("globalexceptiontest")
  2.  
    public Object globalExceptionTest(@Validated @RequestBody BeanValidation data)
  3.  
    {
  4.  
    ResultMsg resultMsg = new ResultMsg(ResultStatusCode.OK.getErrcode(), ResultStatusCode.OK.getErrmsg(), data);
  5.  
    return resultMsg;
  6.  
    }


3、如果未添加全局异常处理,将会使用默认的异常处理,返回结果,如下图

返回的结果和自己的数据结构有很大的差异,对于前端处理返回结果也很麻烦

4、自定义参数异常返回的数据类ArgumentInvalidResult

  1.  
    package com.xiaofangtech.sunt.utils;
  2.  
     
  3.  
    public class ArgumentInvalidResult {
  4.  
    private String field;
  5.  
    private Object rejectedValue;
  6.  
    private String defaultMessage;
  7.  
     
  8.  
    public String getField() {
  9.  
    return field;
  10.  
    }
  11.  
    public void setField(String field) {
  12.  
    this.field = field;
  13.  
    }
  14.  
    public Object getRejectedValue() {
  15.  
    return rejectedValue;
  16.  
    }
  17.  
    public void setRejectedValue(Object rejectedValue) {
  18.  
    this.rejectedValue = rejectedValue;
  19.  
    }
  20.  
    public String getDefaultMessage() {
  21.  
    return defaultMessage;
  22.  
    }
  23.  
    public void setDefaultMessage(String defaultMessage) {
  24.  
    this.defaultMessage = defaultMessage;
  25.  
    }
  26.  
    }



5、添加全局异常处理类GlobalExceptionHandler

  1.  
    package com.xiaofangtech.sunt.exception;
  2.  
     
  3.  
    import java.util.ArrayList;
  4.  
    import java.util.List;
  5.  
     
  6.  
    import javax.servlet.http.HttpServletRequest;
  7.  
     
  8.  
    import org.springframework.validation.FieldError;
  9.  
    import org.springframework.web.bind.MethodArgumentNotValidException;
  10.  
    import org.springframework.web.bind.annotation.ControllerAdvice;
  11.  
    import org.springframework.web.bind.annotation.ExceptionHandler;
  12.  
    import org.springframework.web.bind.annotation.ResponseBody;
  13.  
     
  14.  
    import com.xiaofangtech.sunt.utils.ArgumentInvalidResult;
  15.  
    import com.xiaofangtech.sunt.utils.ResultMsg;
  16.  
    import com.xiaofangtech.sunt.utils.ResultStatusCode;
  17.  
     
  18.  
    @ControllerAdvice
  19.  
    //如果返回的为json数据或其它对象,添加该注解
  20.  
    @ResponseBody
  21.  
    public class GlobalExceptionHandler {
  22.  
    //添加全局异常处理流程,根据需要设置需要处理的异常,本文以MethodArgumentNotValidException为例
  23.  
    @ExceptionHandler(value=MethodArgumentNotValidException.class)
  24.  
    public Object MethodArgumentNotValidHandler(HttpServletRequest request,
  25.  
    MethodArgumentNotValidException exception) throws Exception
  26.  
    {
  27.  
    //按需重新封装需要返回的错误信息
  28.  
    List<ArgumentInvalidResult> invalidArguments = new ArrayList<>();
  29.  
    //解析原错误信息,封装后返回,此处返回非法的字段名称,原始值,错误信息
  30.  
    for (FieldError error : exception.getBindingResult().getFieldErrors()) {
  31.  
    ArgumentInvalidResult invalidArgument = new ArgumentInvalidResult();
  32.  
    invalidArgument.setDefaultMessage(error.getDefaultMessage());
  33.  
    invalidArgument.setField(error.getField());
  34.  
    invalidArgument.setRejectedValue(error.getRejectedValue());
  35.  
    invalidArguments.add(invalidArgument);
  36.  
    }
  37.  
     
  38.  
    ResultMsg resultMsg = new ResultMsg(ResultStatusCode.PARAMETER_ERROR.getErrcode(), ResultStatusCode.PARAMETER_ERROR.getErrmsg(), invalidArguments);
  39.  
    return resultMsg;
  40.  
    }
  41.  
    }



6、运行测试

1、当参数合法

当参数非法,返回与参数合法时有相同风格的错误信息

原文地址:https://www.cnblogs.com/fulong133/p/13858277.html