java constraints @pattern null,在SpringMVC中使用数据验证组件——hibernate-validator

在做web开发的时候,经常需要对客户端发送过来的数据进行一个验证,以防数据不合法。而SpringMVC支持的数据校验是JSR303的标准,通过在bean的属性上打上annotation @NotNull @Max等注解进行验证。JSR303提供有很多annotation借口,而SpringMVC对于这些验证是使用hibernate的实现,所以我们需要添加hibernate的一个validator包:

org.hibernate

hibernate-validator

5.4.1.Final

Spring配置文件内容如下:

xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

xmlns:context="http://www.springframework.org/schema/context"

xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:p="http://www.springframework.org/schema/p"

xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">

p:prefix="/" p:suffix=".jsp"

/>

hibernate除了JSR303的标准之外还额外提供了其他的验证注解。下表是JSR303支持的验证注解:

99d7c2766a7bb0ca2fc5189f7e681038.png

Hibernate Validator 附加的注解:

3e581e790e7ab4910513eca72ad5eccf.png

下面我们来写个小demo,具体演示一下如何使用。例如,我要验证一些字段不能为空,那么就可以使用@NotNull这个注解,如下示例:

package org.zero01.test;

import javax.validation.constraints.NotNull;

public class UserRegister {

@NotNull(message = "用户名不能为空")

private String userName;

@NotNull(message = "密码不能为空")

private String password;

@NotNull(message = "联系地址不能为空")

private String address;

@NotNull(message = "电话号码不能为空")

private String phone;

...getter and setter...

在控制器的方法参数中,需要通过声明BindingResult参数来获得验证出错的信息,然后使用@Valid注解来配置哪个pojo对象需要校验,控制器代码如下:

package org.zero01.test;

import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

import org.springframework.validation.BindingResult;

import org.springframework.validation.FieldError;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import javax.validation.Valid;

@Controller

public class Test {

@RequestMapping(value = "/test.do", method = RequestMethod.GET)

// 注意,@Valid和BindingResult是配对出现,并且形参顺序是固定的(一前一后),不然就会返回400状态码

public String test(@Valid UserRegister userRegister, BindingResult bindingResult, Model model) {

// 判断是否有异常

if (bindingResult.hasErrors()) {

System.out.println("客户端的请求数据异常,所有的异常如下:");

// 取出所有的异常对象

for (FieldError fieldError : bindingResult.getFieldErrors()) {

// 打印异常的字段以及异常信息

System.out.println(fieldError.getField() + " : " + fieldError.getDefaultMessage());

}

return "register";

}

return "index";

}

}

使用Postman进行访问,什么参数都不写:

f1b53204191aeab53e2287c4f05746ef.png

控制台输出结果如下:

客户端的请求数据异常,所有的异常如下:

address : 联系地址不能为空

userName : 用户名不能为空

password : 密码不能为空

phone : 电话号码不能为空

下面再来演示一下其他常用的注解:

package org.zero01.test;

import org.hibernate.validator.constraints.Email;

import org.hibernate.validator.constraints.Length;

import javax.validation.constraints.NotNull;

import javax.validation.constraints.Pattern;

public class UserRegister {

@NotNull(message = "用户名不能为空")

private String userName;

@NotNull(message = "密码不能为空")

@Length(max = 12, min = 6, message = "密码长度需在6-12位之间")

private String password;

@NotNull(message = "联系地址不能为空")

private String address;

@NotNull(message = "电话号码不能为空")

// 指定正则表达式验证格式

@Pattern(regexp = "^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0,5-9]))\\\\d{8}$", message = "电话号码格式错误")

private String phone;

@Email(message = "邮箱格式错误")

private String email;

@Size(max = 10, min = 1, message = "成绩单列表长度需在1-10之间")

public List resultList;

...getter and setter...

控制器代码和之前一致,略。

使用Postman进行访问,如下:

99831185b96760df8f5e2905ac739fb7.png

控制台输出结果如下:

客户端的请求数据异常,所有的异常如下:

address : 联系地址不能为空

userName : 用户名不能为空

password : 密码长度需在6-12位之间

phone : 电话号码格式错误

email : 邮箱格式错误

resultList : 成绩单列表长度需在1-10之间

以上我们都是对所有的字段进行验证,如果我希望有些字段不被验证或者分开验证该怎么办呢?这时候我们就需要到分组验证了,首先编写一个接口:

package org.zero01.test;

public interface Group {

}

然后在需要分组的字段上的注解中加上groups属性,该属性的值为以上我们所定义的接口类,如下示例:

package org.zero01.test;

import org.hibernate.validator.constraints.Email;

import org.hibernate.validator.constraints.Length;

import javax.validation.constraints.NotNull;

import javax.validation.constraints.Pattern;

public class UserRegister {

// groups 属性用于指定分组,值为一个接口类

@NotNull(message = "用户名不能为空", groups = Group.class)

private String userName;

@NotNull(message = "密码不能为空", groups = Group.class)

@Length(max = 12, min = 6, message = "密码长度需在6-12位之间", groups = Group.class)

private String password;

@NotNull(message = "联系地址不能为空")

private String address;

@NotNull(message = "电话号码不能为空")

@Pattern(regexp = "^((13[0-9])|(14[5|7])|(15([0-3]|[5-9]))|(18[0,5-9]))\\\\d{8}$", message = "电话号码格式错误")

private String phone;

@Email(message = "邮箱格式错误")

private String email;

...getter and setter...

控制器代码如下:

package org.zero01.test;

import org.springframework.stereotype.Controller;

import org.springframework.ui.Model;

import org.springframework.validation.BindingResult;

import org.springframework.validation.FieldError;

import org.springframework.validation.annotation.Validated;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import javax.validation.Valid;

@Controller

public class Test {

@RequestMapping(value = "/test.do", method = RequestMethod.GET)

// 分组的情况下需要使用Validated注解来指定接口

public String test(@Validated(Group.class) UserRegister userRegister, BindingResult bindingResult, Model model) {

if (bindingResult.hasErrors()) {

System.out.println("客户端的请求数据异常,所有的异常如下:");

for (FieldError fieldError : bindingResult.getFieldErrors()) {

System.out.println(fieldError.getField() + " : " + fieldError.getDefaultMessage());

}

return "register";

}

return "index";

}

}

访问方式和之前一致,略。

控制台输出结果如下:

客户端的请求数据异常,所有的异常如下:

password : 密码长度需在6-12位之间

userName : 用户名不能为空

如上,从控制台的打印结果中,可以看到只有password以及userName两个字段受到了验证,这是因为我们只在这两个字段上的注解中指定了groups 属性。所以分组验证就是只验证指定组的字段,而这个组的划分是以接口来划分的。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值