• 技术文章 > php教程 > java教程

    spring validation作为数据校验的方法介绍(附代码)

    不言 不言 2019-02-13 15:44:38 转载 171
    本篇文章给大家带来的内容是关于spring validation作为数据校验的方法介绍(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

    数据的校验是交互式网站一个不可或缺的功能,前端的js校验可以涵盖大部分的校验职责,如用户名唯一性,生日格式,邮箱格式校验等等常用的校验。但是为了避免用户绕过浏览器,使用http工具直接向后端请求一些违法数据,服务端的数据校验也是必要的,可以防止脏数据落到数据库中,如果数据库中出现一个非法的邮箱格式,也会让运维人员头疼不已。

    JSR303/JSR-349,hibernate validation,spring validation之间的关系。JSR303是一项标准,JSR-349是其的升级版本,添加了一些新特性,他们规定一些校验规范即校验注解,如@Null,@NotNull,@Pattern,他们位于javax.validation.constraints包下,只提供规范不提供实现。而hibernate validation是对这个规范的实践(不要将hibernate和数据库orm框架联系在一起),他提供了相应的实现,并增加了一些其他校验注解,如@Email,@Length,@Range等等,他们位于org.hibernate.validator.constraints包下。而万能的spring为了给开发者提供便捷,对hibernate validation进行了二次封装,显示校验validated bean时,你可以使用spring validation或者hibernate validation,而spring validation另一个特性,便是其在springmvc模块中添加了自动校验,并将校验信息封装进了特定的类中。这无疑便捷了我们的web开发。本文主要介绍在springmvc中自动校验的机制。

    引入依赖
    我们使用maven构建springboot应用来进行demo演示。

    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
    </dependencies>

    我们只需要引入spring-boot-starter-web依赖即可,如果查看其子依赖,可以发现如下的依赖:

    <dependency>
        <groupId>org.hibernate</groupId>
        <artifactId>hibernate-validator</artifactId>
    </dependency>
    <dependency>
        <groupId>com.fasterxml.jackson.core</groupId>
        <artifactId>jackson-databind</artifactId>
    </dependency>

    验证了我之前的描述,web模块使用了hibernate-validation,并且databind模块也提供了相应的数据绑定功能。

    构建启动类

    无需添加其他注解,一个典型的启动类

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

    创建需要被校验的实体类

    public class Foo {
    
        @NotBlank
        private String name;
    
        @Min(18)
        private Integer age;
    
        @Pattern(regexp = "^1(3|4|5|7|8)\\d{9}$",message = "手机号码格式错误")
        @NotBlank(message = "手机号码不能为空")
        private String phone;
    
        @Email(message = "邮箱格式错误")
        private String email;
    
        //... getter setter
    
    }

    使用一些比较常用的校验注解,还是比较浅显易懂的,字段上的注解名称即可推断出校验内容,每一个注解都包含了message字段,用于校验失败时作为提示信息,特殊的校验注解,如Pattern(正则校验),还可以自己添加正则表达式。

    在@Controller中校验数据

    @Controller
    public class FooController {
    
        @RequestMapping("/foo")
        public String foo(@Validated Foo foo <1>, BindingResult bindingResult <2>) {
            if(bindingResult.hasErrors()){
                for (FieldError fieldError : bindingResult.getFieldErrors()) {
                    //...
                }
                return "fail";
            }
            return "success";
        }
    
    }

    值得注意的地方:

    <1> 参数Foo前需要加上@Validated注解,表明需要spring对其进行校验,而校验的信息会存放到其后的BindingResult中。注意,必须相邻,如果有多个参数需要校验,形式可以如下。foo(@Validated Foo foo, BindingResult fooBindingResult ,@Validated Bar bar, BindingResult barBindingResult);即一个校验类对应一个校验结果。

    <2> 校验结果会被自动填充,在controller中可以根据业务逻辑来决定具体的操作,如跳转到错误页面。

    一个最基本的校验就完成了,总结下框架已经提供了哪些校验:

    JSR提供的校验注解:         
    @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=)  被注释的元素必须在合适的范围内

    分组校验

    如果同一个类,在不同的使用场景下有不同的校验规则,那么可以使用分组校验。未成年人是不能喝酒的,而在其他场景下我们不做特殊的限制,这个需求如何体现同一个实体,不同的校验规则呢?

    改写注解,添加分组:

    Class Foo{
    
        @Min(value = 18,groups = {Adult.class})
        private Integer age;
    
        public interface Adult{}
    
        public interface Minor{}
    }

    这样表明,只有在Adult分组下,18岁的限制才会起作用。

    Controller层改写:

    @RequestMapping("/drink")
    public String drink(@Validated({Foo.Adult.class}) Foo foo, BindingResult bindingResult) {
        if(bindingResult.hasErrors()){
            for (FieldError fieldError : bindingResult.getFieldErrors()) {
                //...
            }
            return "fail";
        }
        return "success";
    }
    
    @RequestMapping("/live")
    public String live(@Validated Foo foo, BindingResult bindingResult) {
        if(bindingResult.hasErrors()){
            for (FieldError fieldError : bindingResult.getFieldErrors()) {
                //...
            }
            return "fail";
        }
        return "success";
    }

    drink方法限定需要进行Adult校验,而live方法则不做限制。

    基于方法校验

    @RestController
    @Validated <1>
    public class BarController {
    
        @RequestMapping("/bar")
        public @NotBlank <2> String bar(@Min(18) Integer age <3>) {
            System.out.println("age : " + age);
            return "";
        }
    
        @ExceptionHandler(ConstraintViolationException.class)
        public Map handleConstraintViolationException(ConstraintViolationException cve){
            Set<ConstraintViolation<?>> cves = cve.getConstraintViolations();<4>
            for (ConstraintViolation<?> constraintViolation : cves) {
                System.out.println(constraintViolation.getMessage());
            }
            Map map = new HashMap();
            map.put("errorCode",500);
            return map;
        }
    
    }

    <1> 为类添加@Validated注解

    <2> <3> 校验方法的返回值和入参

    <4> 添加一个异常处理器,可以获得没有通过校验的属性相关信息

    以上就是spring validation作为数据校验的方法介绍(附代码)的详细内容,更多请关注php中文网其它相关文章!

    第六期线上培训班
    专题推荐: springboot spring java
    上一篇:依赖包的优先级设置的方法介绍 下一篇:SpringBoot在IntelliJ IDEA中实现热部署的图文教程

    相关文章推荐

    • SpringBoot+Thymeleaf实现html文件引入(类似include功能)_html/css_WEB-ITnose • 详解SpringBoot中实现依赖注入功能 • 分享几个在IDEA上面搭建SpringBoot的web-mvc项目常见问题 • 详解springboot集成mybatis的代码实例 • 深度解析springboot如何配置多个redis连接

    全部评论我要评论

  • 取消 发布评论 发送
  • PHP中文网