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

Spring系列 专栏收录该内容
50 篇文章 0 订阅

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();
    }
}

 

  • 3
    点赞
  • 0
    评论
  • 7
    收藏
  • 一键三连
    一键三连
  • 扫一扫,分享海报

相关推荐
©️2020 CSDN 皮肤主题: Age of Ai 设计师:meimeiellie 返回首页
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值