当前位置 博文首页 > xzh_blog:Spring Boot 全局异常处理 与 Hibernate Validator校

    xzh_blog:Spring Boot 全局异常处理 与 Hibernate Validator校

    作者:[db:作者] 时间:2021-08-19 15:43

    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 {
        static final long serialVersionUID = 1L;
    
        /**
         * 0:成功 1:失败
         */
        private int code;
    
        /**
         * 信息
         */
        private String msg;
    
        /**
         * 数据
         */
        private T data;
    
        /**
         * 失败情况
         *
         * @param msg
         */
        public ResponseMessage(String msg) {
            this.code = 1;
            this.msg = msg;
            this.data = null;
        }
    
        /**
         * 成功情况
         *
         * @param data
         */
        public ResponseMessage(T data) {
            this.code = 0;
            this.msg = null;
            this.data = data;
        }
    
        public ResponseMessage(int code, String msg, T data) {
            this.code = code;
            this.msg = msg;
            this.data = data;
        }
    }

    ?

    全局异常捕获处理

    import com.alibaba.fastjson.JSONException;
    import lombok.extern.slf4j.Slf4j;
    import org.springframework.dao.DataIntegrityViolationException;
    import org.springframework.http.converter.HttpMessageConversionException;
    import org.springframework.http.converter.HttpMessageNotReadableException;
    import org.springframework.jdbc.BadSqlGrammarException;
    import org.springframework.validation.BindException;
    import org.springframework.web.HttpMediaTypeNotSupportedException;
    import org.springframework.web.HttpRequestMethodNotSupportedException;
    import org.springframework.web.bind.MethodArgumentNotValidException;
    import org.springframework.web.bind.MissingServletRequestParameterException;
    import org.springframework.web.bind.annotation.ExceptionHandler;
    import org.springframework.web.bind.annotation.RestControllerAdvice;
    
    import javax.servlet.http.HttpServletRequest;
    import java.io.PrintWriter;
    import java.io.StringWriter;
    
    /**
     * 全局异常处理
     *
     * @author 向振华
     * @date 2018/11/21 10:37
     */
    @Slf4j
    @RestControllerAdvice
    public class GlobalExceptionHandler {
    
        /**
         * 参数绑定异常
         */
        @ExceptionHandler(value = BindException.class)
        public Object handler(BindException exception) {
            String msg = exception.getBindingResult().getFieldError().getDefaultMessage();
            return new ResponseMessage<>(msg);
        }
    
        /**
         * 参数类型转换错误
         */
        @ExceptionHandler(HttpMessageConversionException.class)
        public Object handler(HttpMessageConversionException exception) {
            return new ResponseMessage<>("参数类型错误");
        }
    
    
        /**
         * 参数验证异常
         *
         * @param exception
         * @return
         */
        @ExceptionHandler(value = MethodArgumentNotValidException.class)
        public Object handler(MethodArgumentNotValidException exception) {
            String message = exception.getBindingResult().getAllErrors().get(0).getDefaultMessage();
            return new ResponseMessage<>(message);
        }
    
        /**
         * 参数格式异常
         *
         * @param exception
         * @return
         */
        @ExceptionHandler(value = HttpMessageNotReadableException.class)
        public Object handler(HttpMessageNotReadableException exception) {
            return new ResponseMessage<>("参数格式错误");
        }
    
        /**
         * 请求方式异常
         *
         * @param exception
         * @return
         */
        @ExceptionHandler(value = HttpRequestMethodNotSupportedException.class)
        public Object handler(HttpRequestMethodNotSupportedException exception) {
            return new ResponseMessage<>("请求方式错误");
        }
    
        /**
         * 媒体类型异常
         *
         * @param exception
         * @return
         */
        @ExceptionHandler(value = HttpMediaTypeNotSupportedException.class)
        public Object handler(HttpMediaTypeNotSupportedException exception) {
            return new ResponseMessage<>("媒体类型错误");
        }
    
    
        /**
         * 请求参数丢失
         *
         * @param exception
         * @return
         */
        @ExceptionHandler({MissingServletRequestParameterException.class})
        public ResponseMessage<String> handler(MissingServletRequestParameterException exception) {
            return new ResponseMessage<>(exception.getMessage());
        }
    
        /**
         * 业务异常
         *
         * @param exception
         * @return
         */
        @ExceptionHandler(value = BusinessException.class)
        public Object handler(BusinessException exception) {
            return new ResponseMessage<>(exception.getMsg());
        }
    
        /**
         * 未知异常
         *
         * @param request
         * @param exception
         * @return
         */
        @ExceptionHandler(value = Exception.class)
        public Object handler(HttpServletRequest request, Exception exception) {
            log.error("异常---> ", exception);
            String message;
            if (exception instanceof JSONException) {
                message = "JSON解析错误";
            } else if (exception instanceof NumberFormatException) {
                message = "数字转换错误";
            } else if (exception instanceof DataIntegrityViolationException) {
                message = "SQL完整性违规";
            } else if (exception instanceof BadSqlGrammarException) {
                message = "SQL语法错误";
            } else {
                message = "网络异常,请稍后重试";
            }
            String errorLog = errorLog(request, exception);
            // 可以发送邮件通知开发者
            return new ResponseMessage<>(message);
        }
    
        private String errorLog(HttpServletRequest request, Exception exception) {
            StringWriter sw = new StringWriter();
            sw.append(String.format("【url】 %s\n", request.getRequestURI()));
            sw.append("----------------------------------------\n");
            exception.printStackTrace(new PrintWriter(sw));
            return sw.toString();
        }
    }

    ?

    cs