首页 > 其他分享 >springboot集成hibernate-validator

springboot集成hibernate-validator

时间:2022-09-07 12:46:45浏览次数:60  
标签:hibernate springboot rs class validator message RsData public String

一、项目搭建

1、使用springboot搭建一个web工程

建web工程,不使用骨架创建maven的Java工程即可,不需要创建maven的web工程。

2、添加父工程坐标和添加web启动器

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.0.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>RELEASE</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>

查看spring-boot-starter-web依赖,发现web模块默认使用了hibernate-validator:

3、创建启动类

@SpringBootApplication
public class MySpringBootApplication {
    public static void main(String[] args) {
        SpringApplication.run(MySpringBootApplication.class);
    }
}

4、创建实体类Agent

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
@Data
public class Agent {
    /**
     * 代理人姓名
     */
    @NotNull(message = "姓名不能为空")
    private String name;
    /**
     * 联系人邮箱
     */
    @NotBlank(message = "邮箱不能为空")
    private String email;
}

注意:一定要加@Data注解,否则无法获取请求体中的值,即使请求体中参数不为空,也会校验失败。

注意:如果使用@NotNull,如果是空字符串就不会报错。而用NotBlank,空字符串也会报错。

通过注释名即可推断出校验的内容,message用作校验失败时的提示信息。

5、编写controller

@RestController
public class TestController {
    @PostMapping( "/test")
    public String add(@RequestBody @Validated Agent agent) {
        return "你好";
    }
}

6、使用postman发起请求

结果如下:

{
    "timestamp": "2022-09-07T03:48:12.999+0000",
    "status": 400,
    "error": "Bad Request",
    "errors": [
        {
            "codes": [
                "NotBlank.agent.email",
                "NotBlank.email",
                "NotBlank.java.lang.String",
                "NotBlank"
            ],
            "arguments": [
                {
                    "codes": [
                        "agent.email",
                        "email"
                    ],
                    "arguments": null,
                    "defaultMessage": "email",
                    "code": "email"
                }
            ],
            "defaultMessage": "邮箱不能为空",
            "objectName": "agent",
            "field": "email",
            "rejectedValue": "",
            "bindingFailure": false,
            "code": "NotBlank"
        }
    ],
    "message": "Validation failed for object='agent'. Error count: 1",
    "path": "/test"
}

二、统一异常处理

1、异常捕获类

经过对校验异常的debug发现,该异常为MethodArgumentNotValidException

import com.zwh.entity.RsData;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.ObjectError;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.RestController;

import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.StringJoiner;


@ControllerAdvice
@RestController
public class ExceptionHandler {

    private String paramValid = "参数不合法:";

    /**
     * 用来处理validation异常,捕获post请求Body实体属性参数校验异常信息
     *
     * @param ex
     * @return
     */
    @org.springframework.web.bind.annotation.ExceptionHandler(MethodArgumentNotValidException.class)
    public RsData resolveMethodArgumentNotValidException(MethodArgumentNotValidException ex) {
        List<ObjectError> objectErrors = ex.getBindingResult().getAllErrors();
        if (!CollectionUtils.isEmpty(objectErrors)) {
            StringJoiner msgJoiner = new StringJoiner(",");
            Set<String> errors = new HashSet<>(objectErrors.size() / 2);
            for (ObjectError objectError : objectErrors) {
                errors.add(objectError.getDefaultMessage());
            }
            for (String error : errors) {
                msgJoiner.add(error);
            }
            String errorMessage = msgJoiner.toString();
            return RsData.fail(paramValid + errorMessage);
        }
        return RsData.fail(paramValid + ex.getMessage());
    }
}

2、返回的响应体类

@Data
public class RsData {

    private static final String SUCCESS = "0";
    private static final String FAIL = "1";

    private String code;

    private Object result;

    private String message;

    public static RsData success(String msg) {
        RsData rs = new RsData();
        rs.setCode(SUCCESS);
        rs.setMessage(msg);
        return rs;
    }

    public static RsData success(String msg, Object result) {
        RsData rs = new RsData();
        rs.setCode(SUCCESS);
        rs.setMessage(msg);
        rs.setResult(result);
        return rs;
    }

    public static RsData error(String msg) {
        RsData rs = new RsData();
        rs.setCode(FAIL);
        rs.setMessage(msg);
        return rs;
    }

    public static RsData error(String msg, Object result) {
        RsData rs = new RsData();
        rs.setCode(FAIL);
        rs.setMessage(msg);
        rs.setResult(result);
        return rs;
    }

    public static RsData fail(String result) {
        RsData rs = new RsData();
        rs.setCode(FAIL);
        rs.setMessage("失败");
        rs.setResult(result);
        return rs;
    }
}

3、修改Controller

@RestController
public class TestController {
    @PostMapping( "/test")
    public RsData add(@RequestBody @Validated Agent agent) {
        return RsData.success("success");
    }
}

4、postman访问

三、分组校验

当我们遇到不同场景需要有不同的校验规则时候,我们可以使用分组校验。如:一个请求只校验姓名,一个请求只校验email

1、创建分组接口

名称自定义,也不需要实现,只是能做区分分组就行

FirstGroup.class

public interface FirstGroup {
}

SecondGroup.class

public interface SecondGroup {
}

2、实体类中使用分组

import javax.validation.constraints.NotBlank;
@Data
public class Agent {
    /**
     * 代理人姓名
     */
    @NotBlank(message = "姓名不能为空",groups = SecondGroup.class)
    private String name;
    /**
     * 联系人邮箱
     */
    @NotBlank(message = "邮箱不能为空",groups = FirstGroup.class)
    private String email;

}

注意:如果将email划入FirstGroup,将name划到SecondGroup,而@Validated注解不指定分组(默认为Default),

@RestController
public class TestController {
    @PostMapping( "/test")
    public RsData add(@RequestBody @Validated Agent agent) {
        return RsData.success("success");
    }
}

此时由于Default分组没有要校验的属性,相当于不校验,结果如下:

{
    "code": "0",
    "result": null,
    "message": "success"
}

3、修改controller

(1)、当指定FirstGroup时:

@RestController
public class TestController {
    @PostMapping( "/test")
    public RsData add(@RequestBody @Validated(FirstGroup.class) Agent agent) {
        return RsData.success("success");
    }
}

结果如下:

{
    "code": "1",
    "result": "参数不合法:邮箱不能为空",
    "message": "失败"
}

(2)、当指定SecondGroup时

@RestController
public class TestController {
    @PostMapping( "/test")
    public RsData add(@RequestBody @Validated(SecondGroup.class) Agent agent) {
        return RsData.success("success");
    }
}

结果如下:

{
    "code": "1",
    "result": "参数不合法:姓名不能为空",
    "message": "失败"
}

(3)、当不指定分组时

当然不写时会有一个默认分组,所有不指定分组的属性都划到这个分组

实体类:

@Data
public class Agent {
    /**
     * 代理人姓名
     */
    @NotBlank(message = "姓名不能为空")
    private String name;
    /**
     * 联系人邮箱
     */
    @NotBlank(message = "邮箱不能为空")
    private String email;

}

controller

@RestController
public class TestController {
    @PostMapping( "/test")
    public RsData add(@RequestBody @Validated Agent agent) {
        return RsData.success("success");
    }
}

测试

{
    "code": "1",
    "result": "参数不合法:邮箱不能为空,姓名不能为空",
    "message": "失败"
}

修改实体类:

import javax.validation.constraints.NotBlank;
import javax.validation.groups.Default;

@Data
public class Agent {
    /**
     * 代理人姓名
     */
    @NotBlank(message = "姓名不能为空",groups = Default.class)
    private String name;
    /**
     * 联系人邮箱
     */
    @NotBlank(message = "邮箱不能为空",groups = Default.class)
    private String email;

}

修改controller

@RestController
public class TestController {
    @PostMapping( "/test")
    public RsData add(@RequestBody @Validated(Default.class) Agent agent) {
        return RsData.success("success");
    }
}

结果:

{
    "code": "1",
    "result": "参数不合法:邮箱不能为空,姓名不能为空",
    "message": "失败"
}

四、JSR提供的校验注解API

@Null   被注释的元素必须为 null    
@NotNull    被注释的元素必须不为 null    
@AssertTrue     被注释的元素必须为 true    
@AssertFalse    被注释的元素必须为 false    
@Min(value)     被注释的元素必须是一个数字,其值必须大于等于指定的最小值    
@Max(value)     被注释的元素必须是一个数字,其值必须小于等于指定的最大值    
@DecimalMin(value)  被注释的元素必须是一个数字,其值必须大于等于指定的最小值    
@DecimalMax(value)  被注释的元素必须是一个数字,其值必须小于等于指定的最大值    
@Size(max=, min=)   被注释的元素的大小必须在指定的范围内    
@Digits (integer, fraction)     被注释的元素必须是一个数字,其值必须在可接受的范围内    
@Past   被注释的元素必须是一个过去的日期    
@Future     被注释的元素必须是一个将来的日期    
@Pattern(regex=,flag=)  被注释的元素必须符合指定的正则表达式

Hibernate Validator提供的校验注解

@NotBlank(message =)   验证字符串非null,且长度必须大于0    
@Email  被注释的元素必须是电子邮箱地址    
@Length(min=,max=)  被注释的字符串的大小必须在指定的范围内    
@NotEmpty   被注释的字符串的必须非空    
@Range(min=,max=,message=)  被注释的元素必须在合适的范围内

 

标签:hibernate,springboot,rs,class,validator,message,RsData,public,String
From: https://www.cnblogs.com/zwh0910/p/16664602.html

相关文章

  • SpringBoot使用自定义注解+AOP+Redis实现接口限流
    为什么要限流系统在设计的时候,我们会有一个系统的预估容量,长时间超过系统能承受的TPS/QPS阈值,系统有可能会被压垮,最终导致整个服务不可用。为了避免这种情况,我们就需要对......
  • SpringBoot常用注解
    SpringBoot常用注解1.@SpringBootApplicationspringBoot的基石,启动类@Configuration应许spring注册额外的bean或者导入其他配置类@EnableAutoConfiguration启用Sp......
  • Springboot定义全局异常类详解
    前言当我们在开发过程中,会因为一些异常程序出现500,如果直接显示给客户看,这样很不友好。并且对我们后期维护,排查bug很困难。准备1.创建一个SpringBoot项目,引入web依赖,......
  • springboot官方文档解读
    官网地址:https://docs.spring.io/spring-boot/docs/2.7.3/reference/htmlsingle/1第一个springboot项目我们在一个路径下面创建pom.xml文件<?xmlversion="1.0"encod......
  • [安装配置] SpringBoot项目部署
    打包SpringBoot项目 部署方式一:手动部署1、将打包好的jar包上传到Linux服务器中mkdir-p/opt/java62/app2、前台启动SpringBoot应用编译jar包:java-jarhellowor......
  • SpringBoot-整合Druid
    1.添加jar包<dependency><groupId>com.alibaba</groupId><artifactId>druid-spring-boot-starter</artifactId><version>1.2.8</version></dependency>......
  • 14.Springboot多环境配置2
    1.主配置文件application.ymlspring:profiles:active:@profile.active@#需要在pom文件中指定变量#active:pro#include:mvcgroup:"pro......
  • springboot聚合项目搭建
    springboot聚合项目搭建1、简介1.1、什么是聚合项目?一个项目中包含多个子项目的项目。结构:|-父模块---|子模块1---|子模块2---|子模块31.2、聚合项目有什么......
  • springboot Invalid bound statement (not found): com.xx.dao.%Dao.login
    解决方法:需要注意一下application.xml配置文件的MyBatis的配置的mapper-locations的路径参考的这篇博客:(133条消息)Invalidboundstatement(notfound):com.exampl......
  • springboot配置swagger2线上文档
     1、先上项目配置好的swagger2的ui界面:  2、需要swagger2的这两个包:<!--swagger2包--><dependency><groupId>io.springfox</g......