SpringBoot--JSR303验证传入参数
2017-05-19 11:20
295 查看
程序工具类:
一、常用的校验注解
(1)常用标签
@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(value) 被注释的元素必须符合指定的正则表达式。
@Email 被注释的元素必须是电子邮件地址
@Length 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串必须非空
@Range 被注释的元素必须在合适的范围内
(2)示例
二、自定义验证标签
针对某些需求,现有的标签无法满足我们的需要的时候,就需要我们定义自己的标签。实例如下:
(1)定义标签
(4)测试Controller
三、分组验证
当我们针对同一个model的校验不一样的时候该怎么办?比如针对同一个model的添加和修改的时候?这个时候我们就需要采用分组验证。
(1)定义分别代表修改和添加校验规则的接口
四、Controller方法中的非对象参数验证
如果我们传入的参数没必要进行封装成对象,那么这个时候对参数的校验就得使用参数验证了。
(1)添加参数验证配置类
(2)在Controller上添加参数验证
源代码请参考gitHub地址:SpringBoot__validatot
package com.liutao.utilitys; import org.springframework.http.HttpStatus; import org.springframework.validation.BindingResult; import org.springframework.validation.ObjectError; import javax.servlet.http.HttpServletResponse; import java.util.List; /** * 参数验证工具类 * * @author LIUTAO * @version 2017/5/19 * @see * @since */ public class ValidateUtility { /** * 判断是否有验证错误信息 * @param result * @return */ public static String judgeValidate(BindingResult result, HttpServletResponse response) { if(result.hasErrors()){ List<ObjectError> list = result.getAllErrors(); StringBuilder stringBuilder = new StringBuilder(); for(ObjectError error:list){ stringBuilder.append("\n"+error.getDefaultMessage()); } response.setStatus(HttpStatus.BAD_REQUEST.value()); return stringBuilder.toString(); } return "ok"; } }
一、常用的校验注解
(1)常用标签
@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(value) 被注释的元素必须符合指定的正则表达式。
@Email 被注释的元素必须是电子邮件地址
@Length 被注释的字符串的大小必须在指定的范围内
@NotEmpty 被注释的字符串必须非空
@Range 被注释的元素必须在合适的范围内
(2)示例
package com.liutao.model; import org.hibernate.validator.constraints.Length; import org.hibernate.validator.constraints.NotEmpty; /** * 用户数据模板 * * @author LIUTAO * @version 2017/3/29 * @see * @since */ public class User { @NotEmpty(message = "姓名不能为空") private String name; private Integer age; @NotEmpty(message = "密码不能为空") @Length(min = 6,max = 20,message = "密码长度应该大于6位小于20位") private String password; public User() { } public User(String name, Integer age, String password) { this.name = name; this.age = age; this.password = password; } public String getName() { return name; } public void setName(String name) { this.name = name; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } public String getPassword() { return password; } public void setPassword(String password) { this.password = password; } @Override public String toString() { return "User{" + "name='" + name + '\'' + ", age=" + age + ", password='" + password + '\'' + '}'; } }
package com.liutao.controller; import com.liutao.model.User; import com.liutao.utilitys.ValidateUtility; import com.wordnik.swagger.annotations.Api; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; /** * 用户控制层 * * @author LIUTAO * @version 2017/3/29 * @see */ @RestController @Api(value = "test") @RequestMapping("/liutao/v1") public class UserController { private Logger logger = LoggerFactory.getLogger(UserController.class); @PostMapping(value = "/user") public @ResponseBody String postUser(@Valid @RequestBody User user, BindingResult result, HttpServletResponse response) { return ValidateUtility.judgeValidate(result,response); } }以上运行程序进行相应的测试就可以看到返回对应的错误信息。
二、自定义验证标签
针对某些需求,现有的标签无法满足我们的需要的时候,就需要我们定义自己的标签。实例如下:
(1)定义标签
package com.liutao.annotation; import javax.validation.Constraint; import javax.validation.Payload; import java.lang.annotation.*; import static java.lang.annotation.ElementType.*; import static java.lang.annotation.RetentionPolicy.RUNTIME; /** * 演示自定义参数校验注解 * 校验list集合中是否有null元素 * * @author LIUTAO * @version 2017/5/19 * @see */ @Target({ANNOTATION_TYPE, METHOD, ElementType.FIELD}) @Retention(RUNTIME) @Documented @Constraint(validatedBy = ListNotHasNullValidatorImpl.class)//此处指定了注解的实现类为ListNotHasNullValidatorImpl public @interface ListNotHasNull { /** * 添加value属性,可以作为校验时的条件,若不需要,可去掉此处定义 */ int value() default 0; String message() default "List集合中不能含有null元素"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; /** * 定义List,为了让Bean的一个属性上可以添加多套规则 */ @Target({METHOD, FIELD, ANNOTATION_TYPE, CONSTRUCTOR, PARAMETER}) @Retention(RUNTIME) @Documented @interface List { ListNotHasNull[] value(); } }(2)标签验证实现类
package com.liutao.annotation; import org.springframework.stereotype.Service; import javax.validation.ConstraintValidator; import javax.validation.ConstraintValidatorContext; import java.util.List; /** * 演示实现ListNotHasNull校验注解的实现类 * * @author LIUTAO * @version 2017/5/19 * @see */ @Service public class ListNotHasNullValidatorImpl implements ConstraintValidator<ListNotHasNull, List> { private int value; @Override public void initialize(ListNotHasNull constraintAnnotation) { //传入value 值,可以在校验中使用 this.value = constraintAnnotation.value(); } public boolean isValid(List list, ConstraintValidatorContext constraintValidatorContext) { for (Object object : list) { if (object == null) { //如果List集合中含有Null元素,校验失败 return false; } } return true; } }(3)所需的数据模型
package com.liutao.model; /** * 员工数据模型 * * @author LIUTAO * @version 2017/5/19 * @see */ public class Employee { private String name; private String age; private String cellPhone; public Employee() { } public Employee(String name, String age, String cellPhone) { this.name = name; this.age = age; this.cellPhone = cellPhone; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAge() { return age; } public void setAge(String age) { this.age = age; } public String getCellPhone() { return cellPhone; } public void setCellPhone(String cellPhone) { this.cellPhone = cellPhone; } @Override public String toString() { return "Employee{" + "name='" + name + '\'' + ", age='" + age + '\'' + ", cellPhone='" + cellPhone + '\'' + '}'; } }
package com.liutao.model; import com.liutao.annotation.ListNotHasNull; import org.hibernate.validator.constraints.Length; import org.hibernate.validator.constraints.NotEmpty; import javax.validation.Valid; import java.util.List; /** * 公司数据模型 * * @author LIUTAO * @version 2017/5/19 * @see * @since */ public class Company { @NotEmpty(message = "公司名字不能为空") private String name; @Length(min = 2,max = 20,message = "地址信息必须在2到20个字符之间") private String address; @NotEmpty(message = "员工信息不能为空") @ListNotHasNull @Valid private List<Employee> employees; public Company() { } public Company(String name, String address, List<Employee> employees) { this.name = name; this.address = address; this.employees = employees; } public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } public List<Employee> getEmployees() { return employees; } public void setEmployees(List<Employee> employees) { this.employees = employees; } @Override public String toString() { return "Company{" + "name='" + name + '\'' + ", address='" + address + '\'' + ", employees=" + employees + '}'; } }从上面的Company我们可以看见已经使用了自定义的@ListNotHasNull标签
(4)测试Controller
package com.liutao.controller; import com.liutao.model.Company; import com.liutao.utilitys.ValidateUtility; import com.wordnik.swagger.annotations.Api; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.validation.BindingResult; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import javax.servlet.http.HttpServletResponse; import javax.validation.Valid; /** * 公司Controller * * @author LIUTAO * @version 2017/5/19 * @see */ @RestController @Api(value = "test company") @RequestMapping("/liutao/v1") public class CompanyController { private Logger logger = LoggerFactory.getLogger(UserController.class); @PostMapping(value = "/company") public String postCompany(@Valid @RequestBody Company company, BindingResult result,HttpServletResponse response){ return ValidateUtility.judgeValidate(result,response); } }上面的程序进行相应的测试后就可以看见相应的错误信息。
三、分组验证
当我们针对同一个model的校验不一样的时候该怎么办?比如针对同一个model的添加和修改的时候?这个时候我们就需要采用分组验证。
(1)定义分别代表修改和添加校验规则的接口
package com.liutao.validateInterface; /** * person模型新增时的参数校验规则 * * @author LIUTAO * @version 2017/5/19 * @see * @since */ public interface PersonAddView { }
package com.liutao.validateInterface; /** * person模型修改时的参数校验规则 * * @author LIUTAO * @version 2017/5/19 * @see * @since */ public interface PersonUpdateView { }(2)在数据模型上添加相应的校验规则
package com.liutao.model; import com.liutao.validateInterface.PersonAddView; import com.liutao.validateInterface.PersonUpdateView; import org.hibernate.validator.constraints.Length; import javax.validation.constraints.Max; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; /** * person数据模型 * * @author LIUTAO * @version 2017/5/19 * @see */ public class Person { private Long id; /** * 针对验证标签里面添加groups说明仅仅在特定的验证规则里面起作用,如果不加,那么就在默认的验证规则里面起作用。 */ @NotNull(groups = {PersonAddView.class},message = "添加的姓名不能为空") @Length(min = 2,max = 10,groups = {PersonUpdateView.class},message = "修改时的姓名必须在2到10个字符之间") private String name; @NotNull(groups = {PersonAddView.class}, message = "添加用户时地址不能为空") private String address; @Min(value = 18, groups = {PersonAddView.class}, message = "年龄不能低于18岁") @Max(value = 30, groups = {PersonUpdateView.class}, message = "年龄不能超过30岁") private Integer age; public Person() { } public Person(Long id, String name, String address, Integer age) { this.id = id; this.name = name; this.address = address; this.age = age; } 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 getAddress() { return address; } public void setAddress(String address) { this.address = address; } public Integer getAge() { return age; } public void setAge(Integer age) { this.age = age; } @Override public String toString() { return "Person{" + "id=" + id + ", name='" + name + '\'' + ", address='" + address + '\'' + ", age=" + age + '}'; } }(3)给参数添加校验
package com.liutao.controller; import com.liutao.model.Person; import com.liutao.utilitys.ValidateUtility; import com.liutao.validateInterface.PersonAddView; import com.liutao.validateInterface.PersonUpdateView; import com.wordnik.swagger.annotations.Api; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.validation.BindingResult; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.servlet.http.HttpServletResponse; import javax.validation.groups.Default; /** * 人员Controller * * @author LIUTAO * @version 2017/5/19 * @see * @since */ @RestController @Api(value = "test person") @RequestMapping("/liutao/v1") public class PersonController { private Logger logger = LoggerFactory.getLogger(PersonController.class); /** * 处@Validated(PersonAddView.class) 表示使用PersonAndView这套校验规则,若使用@Valid 则表示使用默认校验规则, * 若两个规则同时加上去,则只有第一套起作用 * * @param person */ @PostMapping(value = "/person") public String addPerson(@RequestBody @Validated({PersonAddView.class, Default.class}) Person person, BindingResult result,HttpServletResponse response) { logger.debug("enter post person"); logger.debug("the information of person :"+ person); return ValidateUtility.judgeValidate(result,response); } /** * 修改Person对象 * 此处启用PersonModifyView 这个验证规则 * @param person */ @PutMapping(value = "/person") public String modifyPerson(@RequestBody @Validated(value = {PersonUpdateView.class}) Person person, BindingResult result,HttpServletResponse response) { logger.debug("enter put person"); logger.debug("the information of person :"+ person); return ValidateUtility.judgeValidate(result,response); } }根据上面的程序进行测试就可以得到相应的测试结果。
四、Controller方法中的非对象参数验证
如果我们传入的参数没必要进行封装成对象,那么这个时候对参数的校验就得使用参数验证了。
(1)添加参数验证配置类
package com.liutao.config; import org.springframework.context.annotation.Bean; import org.springframework.http.HttpStatus; import org.springframework.stereotype.Component; import org.springframework.validation.beanvalidation.MethodValidationPostProcessor; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.bind.annotation.ResponseStatus; import javax.validation.ValidationException; /** * 参数验证配置类 * * @author LIUTAO * @version 2017/5/18 * @see */ @ControllerAdvice @Component public class GlobalExceptionHandler { @Bean public MethodValidationPostProcessor methodValidationPostProcessor() { return new MethodValidationPostProcessor(); } @ExceptionHandler @ResponseBody @ResponseStatus(HttpStatus.BAD_REQUEST) public String handle(ValidationException exception) { return "传入参数不符合要求"; } }
(2)在Controller上添加参数验证
package com.liutao.controller; import com.wordnik.swagger.annotations.Api; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.http.HttpStatus; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.*; import javax.validation.constraints.Min; /** * 员工Controller * * @author LIUTAO * @version 2017/5/19 * @see * @since */ @RestController @Api(value = "test employee") @RequestMapping("/liutao/v1") @Validated public class EmployeeController { private Logger logger = LoggerFactory.getLogger(EmployeeController.class); @GetMapping("/employee") @ResponseStatus(HttpStatus.OK) public @ResponseBody String check(@RequestParam @Min(value = 10,message = "名字长度必须大于10") int age) { logger.debug("enter employee get"); return "ok"; } }以上的程序就可以进行相应的测试得到测试结果。
源代码请参考gitHub地址:SpringBoot__validatot
相关文章推荐
- Kotlin + Spring Boot 请求参数验证
- SpringBoot + Mybatis 的 insert 通过注解传入多个参数
- Kotlin + Spring Boot 请求参数验证的代码实例
- 关于怎么解决从ajax传入的json参数注入到Controller的接收对象 以及如何在Spring Boot项目使用参数校验
- 使用validator-api来验证spring-boot的参数
- spring boot 打成jar包后 通过命令行传入的参数 3中实现方式
- SpringBoot-服务端参数验证-JSR-303验证框架
- 使用validator-api来验证spring-boot的参数
- SpringBoot--JSR303验证传入参数
- 使用validator-api来验证spring-boot的参数
- 使用SpringAop 验证方法参数是否合法
- Spring Boot 中使用log4jdbc记录SQL的运行时参数
- springBoot PUT请求接收不了参数的解决办法
- Spring Boot实战之全局异常捕获 实现参数异常检查返回统一错误信息
- 在Spring Boot中整合Spring Security并自定义验证代码
- spring boot 加入jsp自定义标签对get请求参数加密
- 用spring的断言实现对service的参数验证
- 通过 Spring AOP 验证方法的参数是否合法
- SpringBoot设置Filter过滤请求参数
- SpringBoot自定义参数注解