springboot使用hibernate validator校验

Easter79
• 阅读 699

hibernate validator Bean验证器在开发中常用,这里我们说说它在springboot中的使用

第一步:引入配置

@Bean
    public MethodValidationPostProcessor methodValidationPostProcessor() {
        MethodValidationPostProcessor postProcessor = new MethodValidationPostProcessor();
        /**设置validator模式为快速失败返回*/
        postProcessor.setValidator(validator());
        return postProcessor;
    }

    @Bean
    public Validator validator(){
        //hibernate.validator.fail_fast=false 设置为普通模式返回
        //hibernate.validator.fail_fast=true 设置为快速模式返回
        ValidatorFactory validatorFactory = Validation.byProvider( HibernateValidator.class )
                .configure()
                .addProperty("hibernate.validator.fail_fast", "false" )
                .buildValidatorFactory();
        Validator validator = validatorFactory.getValidator();
        return validator;
    }

它有两种模式返回,一种普通模式,就是所有的属性都要验证,并把错误信息返回,其余一种是快速模式,这种模式是遇到错误就返回,剩下的就不检查了。

第二步:就是使用的问题了

我们使用有两种情况,就是传参的时候我们会传入一个Bean对象或者是单个参数,此时我们处理就分两种情况了。

我们首先看传Bean对象,此时怎么处理。

先建个Bean对象:

import lombok.Data;
import org.hibernate.validator.constraints.NotBlank;

import javax.validation.Valid;
import javax.validation.constraints.NotNull;

/**
 * 我们定义个bean、
 * Created by mingge on 2018/5/24.
 */
@Data
public class NewInfoParam {

    @NotNull(message = "ID不能为空")
    private Long id;

    @NotBlank(message = "名字不能为空")
    private String name;
}

然后在控制层中使用:

@PostMapping("/test")
    public ExtendVO test(@Valid @RequestBody NewInfoParam p, BindingResult result){
        try {
            if(result.hasErrors()){
                for (ObjectError error : result.getAllErrors()) {
                    throw new Exception(error.getDefaultMessage());
                }
            }
            return VOUtils.returnExtendVOSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
            return VOUtils.returnExtendVOError(CodeEnum.ERROR, null);
        }
    }

这里演示BindingResult result这个不是必须的,我们可以通过控制层抛出异常,对其进行统一处理。

第二种就是单个属性验证了:

@PostMapping("/test1")
    public ExtendVO testGet(@NotNull(message = "年龄不能为空") Integer age){
        try{
            return VOUtils.returnExtendVOSuccess(true);
        }catch (Exception e){
            e.printStackTrace();
            return VOUtils.returnExtendVOError(CodeEnum.ERROR, null);
        }
    }

还有就是你需要在这个类上加上:

@Validated 才有效

@GetMapping("/test")
    public ExtendVO test(@RequestParam(name = "name") String name){
        try {
            return VOUtils.returnExtendVOSuccess(true);
        } catch (Exception e) {
            e.printStackTrace();
            return VOUtils.returnExtendVOError(CodeEnum.ERROR, null);
        }
    }

以上这段是springmvc自带的,异常最后处理还是在统一抛出来处理

最后,你需要配置全局统一异常处理:**

* Created by 异常处理 on 2018/5/24.
 */
@ControllerAdvice
@Component
public class GlobalExceptionHandler {

    @ExceptionHandler
    @ResponseBody
    @ResponseStatus(HttpStatus.BAD_REQUEST)
    public String handle(Exception exception) {

        /**
         * 这里验证单个字段属性
         */
        if(exception instanceof ConstraintViolationException){
            ConstraintViolationException exs = (ConstraintViolationException) exception;
            Set<ConstraintViolation<?>> violations = exs.getConstraintViolations();
            for (ConstraintViolation<?> item : violations) {
                /**打印验证不通过的信息*/
                System.out.println(item.getMessage());
            }
        }

        /**
         * 这里验证Bean
         */
        if(exception instanceof MethodArgumentNotValidException) {
            MethodArgumentNotValidException methodArgumentNotValidException = (MethodArgumentNotValidException) exception;
            //按需重新封装需要返回的错误信息
            //解析原错误信息,封装后返回,此处返回非法的字段名称,原始值,错误信息
            for (FieldError error : methodArgumentNotValidException.getBindingResult().getFieldErrors()) {
                ArgumentInvalidResult invalidArgument = new ArgumentInvalidResult();
                invalidArgument.setDefaultMessage(error.getDefaultMessage());
                invalidArgument.setField(error.getField());
                invalidArgument.setRejectedValue(error.getRejectedValue());
                System.out.println("参数异常:"+error.getField()+error.getDefaultMessage());

            }
        }         if(exception instanceof MissingServletRequestParameterException){ //GET请求参数异常处理      //这里可以封装由springmvc自带的    }

return "";
    }
}

it's ok,你可以达到你的大部分目的了。。。

hibernate validator 官网:

 http://docs.jboss.org/hibernate/validator/4.2/reference/zh-CN/html_single/#validator-usingvalidator-annotate

点赞
收藏
评论区
推荐文章
blmius blmius
3年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Karen110 Karen110
3年前
一篇文章带你了解JavaScript日期
日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
待兔 待兔
5个月前
手写Java HashMap源码
HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程HashMap的使用教程22
Jacquelyn38 Jacquelyn38
3年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
Wesley13 Wesley13
3年前
mysql设置时区
mysql设置时区mysql\_query("SETtime\_zone'8:00'")ordie('时区设置失败,请联系管理员!');中国在东8区所以加8方法二:selectcount(user\_id)asdevice,CONVERT\_TZ(FROM\_UNIXTIME(reg\_time),'08:00','0
Stella981 Stella981
3年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Wesley13 Wesley13
3年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
为什么mysql不推荐使用雪花ID作为主键
作者:毛辰飞背景在mysql中设计表的时候,mysql官方推荐不要使用uuid或者不连续不重复的雪花id(long形且唯一),而是推荐连续自增的主键id,官方的推荐是auto_increment,那么为什么不建议采用uuid,使用uuid究
Python进阶者 Python进阶者
11个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这
Easter79
Easter79
Lv1
今生可爱与温柔,每一样都不能少。
文章
2.8k
粉丝
5
获赞
1.2k