SpringBoot Validator入门

jonathan
2017-05-09 / 0 评论

大纲

  1. 入门例子
  2. 国际化
  3. 在代码中添加错误信息

入门例子

Validator 主要是校验用户提交的数据的合理性的,比如是否为空了,密码长度是否大于 6 位,是否是纯数字的,等等。那么在 spring boot 怎么使用这么强大的校验框架呢。

在这里我们主要是使用注解进行学习。我们先说说我们的需求:

我们有一个 demo.html,在页面上有两个元素 姓名输入框,密码输入框,提交按钮。

提交到后台之后,使用 Validator 进行校验,然后如果存在错误,转发到 demo.html

我们先编写一个实体类接收用户的输入,以及使用 Validator 注解校验:

package com.kfit.demo;

import org.hibernate.validator.constraints.Length;
import org.hibernate.validator.constraints.NotEmpty;

public class Demo {
    private long id;

    @NotEmpty(message="姓名不能为空")
    private String name;

    @NotEmpty(message="密码不能为空")
    @Length(min=6,message="密码长度不能小于6位")
    private String password;

    public long getId() {
        return id;
    }

    public void setId(long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(String password) {
        this.password = password;
    }

    @Override
    public String toString() {
        return "Demo [id=" + id + ", name=" + name + ", password=" + password + "]";
    }
}

这个实体类在属性上加入了注解 @NotEmpty@Length,那么常用的注解有:

约束注解名称 约束注解说明
@null 验证对象是否为空
@notnull 验证对象是否为非空
@asserttrue 验证 boolean 对象是否为 true
@assertfalse 验证 boolean 对象是否为 false
@min 验证 number 和 string 对象是否大等于指定的值
@max 验证 number 和 string 对象是否小等于指定的值
@decimalmin 验证 number 和 string 对象是否大等于指定的值,小数存在精度
@decimalmax 验证 number 和 string 对象是否小等于指定的值,小数存在精度
@size 验证对象(array,collection,map,string)长度是否在给定的范围之内
@digits 验证 number 和 string 的构成是否合法
@past 验证 date 和 calendar 对象是否在当前时间之前
@future 验证 date 和 calendar 对象是否在当前时间之后
@pattern 验证 string 对象是否符合正则表达式的规则
@Email 验证邮箱

实际例子:

@size (min=3, max=20, message="用户名长度只能在3-20之间")
@size (min=6, max=20, message="密码长度只能在6-20之间")
@pattern (regexp="[a-za-z0-9._%+-]+@[a-za-z0-9.-]+\\.[a-za-z]{2,4}", message="邮件格式错误")
@Length(min = 5, max = 20, message = "用户名长度必须位于5到20之间")  
@Email(message = "比如输入正确的邮箱")  
@NotNull(message = "用户名称不能为空") 
@Max(value = 100, message = "年龄不能大于100岁") 
@Min(value= 18 ,message= "必须年满18岁!" )  
@AssertTrue(message = "bln4 must is true")
@AssertFalse(message = "blnf must is falase")
@DecimalMax(value="100",message="decim最大值是100")
@DecimalMin(value="100",message="decim最小值是100")
@NotNull(message = "身份证不能为空") 
@Pattern(regexp="^(\\d{18,18}|\\d{15,15}|(\\d{17,17}[x|X]))$", message="身份证格式错误")

好了,这个不是我们这节的重点,这里简单说一下而已,那么之后我们应该怎么做呢?我们需要编写一个 Controller 进行访问的时候,能访问到 demo.html 以及点击提交按钮的处理方法,具体看如下代码:

@RequestMapping("/demo")
public String demo(Model model){
    model.addAttribute("demo",new Demo());
    return "/demo";
}

@RequestMapping("/demoAdd")
public String demoAdd(@Valid Demo demo,BindingResult result,Model model){
    //有错误信息.
    model.addAttribute("demo",demo);
    if(result.hasErrors()){
        List<ObjectError>  list = result.getAllErrors();
        for(ObjectError  error:list){
            System.out.println(error.getCode()+"---"+error.getArguments()+"---"+error.getDefaultMessage());
        }
        return "demo";
    }
    return "/demo";
}

这里的代码还是需要简单说明下,我们使用 @Valid 指定要校验的实体类。

BindingResult 所有的错误信息都会保存在这个类中,我们可以使用 result.hasErrors() 判断是否有错误信息,有的话,我们转发到我们原先访问的 hello.html,如果没有的话,我们正常应该是跳转到 list.html 之类的,这里只是为了方便测试跳回了 demo.html,但是如果没有任何错误信息的话,那么在页面上是不会显示错误信息的。

好了,接下来我们看看 demo.html 是怎么编写的吧?

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />
    <title>hello spring boot</title>
</head>
<body>
    <form action="/demoAdd" method="post" th:object="${demo}">
        <p>姓名:<input type="text" name="name" th:value="*{name}" />
        </p>
        <p th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Name Error</p>
        <p>密码:<input type="text" name="password" th:value="*{password}"  />
        </p>
        <p th:if="${#fields.hasErrors('password')}" th:errors="*{password}">password Error</p>
        <p><button>提交</button></p>
    </form>
</body>
</html>

这里我们使用的 thymeleaf 进行展示数据的,使用 jsp 的代码需要用到 tag 标签,也能实现相同的效果,自行百度学习。这里核心代码就是:

<p th:if="${#fields.hasErrors('name')}" th:errors="*{name}">Name Error</p>

这句代码一旦后台有返回异常信息的话,就会显示 name 对应的 message,如果满足了两个条件的话,是会返回两个的,之间是用 <br/> 进行处理的,就如我们的 password 什么都不填写的情况下是会显示如下信息的:

密码:
密码不能为空
密码长度不能小于6位

国际化

在上一节我们就讲过国际化了,那么如何在 Validator 加入国际化呢,很简单的,只需要在国际化配置文件加入相应的配置如:

demo.name = `name` is not empty.

这里需要注意的地方是:

必须放在 classes 目录下,而且必须用 ValidationMessages 这个名字

也就是文件名称需要命名为:

  • ValidationMessages.properties
  • ValidationMessages_en.properties

那么修改 Demo.java 文件:

@NotEmpty(message="{demo.name}")

在代码中添加错误信息

有些代码是很难使用 Validator 的注解来实现的,那么我们怎么在返回的信息添加我们自己的判断呢,比如我们现在要求用户输入的 name 不能重复,那么势必我们会有这么一段代码: 如果存在 name,那么返回“该 name 已经存在了”。其实这个也是很简单,只需要一句话代码就可以添加自定义错误字段的信息了:

result.rejectValue("name", "misFormat", "这个name已经注册过了!");

当然在添加的时候,外层应该有一个 if(isExist(“name”)) 这样的代码,这里没有进行编写,就直接添加了,实际开发请自行从数据库获取,然后进行判断。

评论

博主关闭了当前页面的评论