Spring Boot 全局异常处理 与 Hibernate Validator校验框架整合

Hibernate Validator校验框架的使用

Spring boot已经集成了hibernate-validator,不需要引入maven,其他框架也可以自己引入:

        <dependency>
            <groupId>org.hibernate</groupId>
            <artifactId>hibernate-validator</artifactId>
            <version>5.3.5.Final</version>
        </dependency>

注解详解(需要校验的model类)

import io.swagger.models.Model;
import org.hibernate.validator.constraints.*;

import javax.validation.Valid;
import javax.validation.constraints.*;
import java.math.BigDecimal;
import java.util.List;

/**
 * @author 向振华
 * @date 2018/11/21 09:59
 */
public class Eg {

    /**空检查*/

    //验证对象是否为null
    @Null(message = "")//message为异常类中的message
    private Model model1;

    //检查基本类型是否为空
    @NotNull(message = "")
    private Integer integer;

    //检查约束字符串是不是Null还有被Trim的长度是否大于0,且会去掉前后空格
    @NotBlank(message = "")
    private String string;

    //检查集合是否为NULL或者是EMPTY
    @NotEmpty(message = "")
    private List<String> stringList;


    /**Booelan检查*/

    //验证 Boolean 对象是否为 true
    @AssertTrue(message = "")
    private Boolean tBoolean;

    //验证 Boolean 对象是否为 false
    @AssertFalse(message = "")
    private Boolean fBoolean;


    /**长度检查*/

    //验证对象(Array,Collection,Map,String)长度是否在给定的范围之内
    @Size(min = 1, max = 100, message = "范围1~100!")
    private List<String> stringLists;

    //验证字符串长度是否在指定范围
    @Length(min=1, max=20, message = "范围1~20")
    private String stringl;


    /**日期检查*/

    //验证 Date 和 Calendar 对象是否在当前时间之前
    @Past()
    private java.util.Date date1;

    //验证 Date 和 Calendar 对象是否在当前时间之后
    @Future()
    private java.util.Date date2;


    /**字符串正则检查*/

    //验证 String 对象是否符合正则表达式的规则
    @Pattern(regexp = "[1][3456789]\\d{9}", message = "手机号格式不正确")
    private String mobile;


    /**数值检查*/
    //建议使用在Stirng,Integer类型,不建议使用在int类型上,因为表单值为“”时无法转换为int,但可以转换为Stirng为"",Integer为null

    //验证 Number 和 String 对象是否大等于指定的值
    @Min(10)
    private Integer integer1;

    //验证 Number 和 String 对象是否小等于指定的值
    @Max(20)
    private Integer integer2;

    //被标注的值必须不大于约束中指定的最大值. 这个约束的参数是一个通过BigDecimal定义的最大值的字符串表示.小数存在精度
    @DecimalMax("10.1")
    private BigDecimal bigDecimal1;

    //被标注的值必须不小于约束中指定的最小值. 这个约束的参数是一个通过BigDecimal定义的最小值的字符串表示.小数存在精度
    @DecimalMin("20.2")
    private BigDecimal bigDecimal2;

    //验证字符串是否是符合指定格式的数字,interger指定整数精度,fraction指定小数精度。
    @Digits(integer= 1,fraction= 2)
    private Integer integerh;

    //验证值是否在指定的范围
    @Range(min=10000,max=50000)
    private BigDecimal wage;

    //递归的对关联对象进行校验, 如果关联对象是个集合或者数组,那么对其中的元素进行递归校验,如果是一个map,则对其中的值部分进行校验.(是否进行递归验证)
    @Valid
    //添加其他注解校验
    private List<Integer> integers;

    //信用卡验证
    @CreditCardNumber

    //验证是否是邮件地址,如果为null,不进行验证,算通过验证。
    @Email
    private String mailbox;

//    @ScriptAssert(lang= ,script=, alias=)

//    @URL(protocol=,host=, port=,regexp=, flags=)
}

需要在Controller方法参数前面加@Validated使校验框架生效

    @Override
    public ResponseMessage send(@RequestBody @Validated Eg eg) {
        return sendService.send(eg);
    }

返回值类 (用于返回给前端固定格式的值)

public class ResponseMessage<T> implements Serializable {
    /**
     * 1:成功 -1:失败
     */
    private int code;
    /**
     * 信息
     */
    private String msg;
    /**
     * 数据
     */
    private T data;
}

全局异常捕获处理

/**
 * 全局异常捕获处理
 * @author 向振华
 * @date 2018/11/21 10:37
 */
@Slf4j
@ControllerAdvice
public class GlobalExceptionHandler {
    private static final Log LOG = LogFactory.getLog(GlobalExceptionHandler.class);

    /**
     * 所有验证框架异常捕获处理
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = {BindException.class, MethodArgumentNotValidException.class})
    public Object validationExceptionHandler(Exception exception) {
        BindingResult bindResult = null;
        if (exception instanceof BindException) {
            bindResult = ((BindException) exception).getBindingResult();
        } else if (exception instanceof MethodArgumentNotValidException) {
            bindResult = ((MethodArgumentNotValidException) exception).getBindingResult();
        }
        String msg;
        if (bindResult != null && bindResult.hasErrors()) {
            msg = bindResult.getAllErrors().get(0).getDefaultMessage();
            if (msg.contains("NumberFormatException")) {
                msg = "参数类型错误!";
            }
        }else {
            msg = "系统繁忙,请稍后重试...";
        }
        return new ResponseMessage(-1, msg);
    }

    /**
     * 业务异常
     * @param exception
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = BusinessException.class)
    public Object allBusinessExceptionHandler(BusinessException exception) {
        return new ResponseMessage(-1, exception.getMessage());
    }

    /**
     * 未知的异常捕获处理
     * @param exception
     * @return
     */
    @ResponseBody
    @ExceptionHandler(value = Exception.class)
    public Object allUnknowExceptionHandler(HttpServletRequest request, Exception exception) {
        String error = logError(request, exception);
        //可以发送邮件通知开发
        return new ResponseMessage(-1, "系统繁忙,请稍后重试!");
    }

    private String logError(HttpServletRequest request, Exception exception) {
        LOG.error("发生未知异常:", exception);
        StringWriter sw = new StringWriter();
        sw.append(String.format("Date:{%s};\n", DateUtil.dateToString(new Date())));
        sw.append(String.format("url:{%s}产生错误;\n", request.getRequestURI()));
        sw.append(String.format("请求IP:{%s};\n", request.getRemoteAddr()));
        sw.append(String.format("type:{%s};\n", request.getMethod()));
        sw.append(String.format("请求参数:{%s};\n", JSONObject.toJSONString(request.getParameterMap())));
        exception.printStackTrace(new PrintWriter(sw));
        return sw.toString();
    }
}

猜你喜欢

转载自blog.csdn.net/Anenan/article/details/84313934
今日推荐