作为服务端开发,验证前端传入的参数的合法性是一个必不可少的步骤,但是验证参数是一个基本上是一个体力活,而且冗余代码繁多,也影响代码的可阅读性,所以有没有一个比较优雅的方式来解决这个问题?
这么简单的问题当然早就有大神遇到并且解决了,这一篇文章主要讲一下解决基于spring-boot的验证参数的比较好的方法:利用validator-api来进行验证参数。
在spring-boot-starter-web
包里面有hibernate-validator
包,它提供了一系列验证各种参数的方法,所以说spring-boot已经帮我们想好要怎么解决这个问题了。
这篇文章针对spring-boot里面的spring-mvc介绍三种方式来验证参数。
(一):这个方法在网上大部分都可以查到,先假设我们的restful的接口接受一个GradeAndClassroomModel
类型的对象,并且这个类被定义成
@Data
public class GradeAndClassroomModel {
@Range(min = 1, max = 9, message = "年级只能从1-9")
private int grade;
@Range(min = 1, max = 99, message = "班级只能从1-99")
private int classroomNumber;
}
利用validator
提供的一系列注解,比如本例中的@Range
,就可以表示参数的范围和出错时候的提示信息。还有很多其他注解,这里就不一一列出
然后我们的Controller层的代码为
@RequestMapping(value = "/paramErrorTest", method = RequestMethod.GET)
public String paramErrorTest(
@Valid
@ModelAttribute
GradeAndClassroomModel gradeAndClassroomModel,
BindingResult result) {
return classroomService.getTeacherName(gradeAndClassroomModel.getGrade(), gradeAndClassroomModel.getClassroomNumber());
}
其中如果验证出错,result对象里面就会有错误信息,然后可以自己进行处理。
(二): 针对上面的例子,会有人说,就两个参数,为什么要作为对象呢?会不会太麻烦?确实,如果只有少数对象,直接把参数写到Controller层,然后在Controller层进行验证就可以了。
@RequestMapping(value = "/teacherName", method = RequestMethod.GET)
public String teacherName(
@Range(min = 1, max = 9, message = "年级只能从1-9")
@RequestParam(name = "grade", required = true)
int grade,
@Min(value = 1, message = "班级最小只能1")
@Max(value = 99, message = "班级最大只能99")
@RequestParam(name = "classroom", required = true)
int classroom) {
return classroomService.getTeacherName(grade, classroom);
}
如果直接把validator
提供的注解移除来写到请求参数上面的话是不是就可以了呢?答案是错,为什么这样不能成功的验证参数呢?具体原因大家可以参考官方文档:http://docs.spring.io/spring-framework/docs/current/spring-framework-reference/htmlsingle/#validation-beanvalidation-spring-method
上面的文档已经说的很清楚了,所以我们需要创建一个Bean
@Bean
public MethodValidationPostProcessor methodValidationPostProcessor() {
return new MethodValidationPostProcessor();
}
然后在类方法上面加上注解@Validated
@RestController
@RequestMapping("/spring-boot/classroom")
@Validated
public class ClassroomController {
...
}
然后之前没有生效的注解@Range
、@Min
、@Max
等validator
包里面提供的注解就可以生效了。
(三)估计到了这里又会有人问,如果validator
包里面注解不能满足我们的需求,我们是否可以自己定义参数验证的逻辑。答案是肯定的,我们可以利用
@Documented
@Retention(RetentionPolicy.RUNTIME)
@Target({ElementType.PARAMETER, ElementType.FIELD})
@Constraint(validatedBy = {Validator.class})
public @interface ParamValidator {
String message() default "Parameter error!";
Class<?>[] groups() default {};
Class<? extends Payload>[] payload() default {};
}
和
public class Validator implements ConstraintValidator<ParamValidator, Object> {
...
}
组合进行自定义,具体的例子网上其他文章就很多了,这里就不进行详细的例子了,但是最终使用的时候就是
@RequestMapping(value = "/paramValidator", method = RequestMethod.GET)
public String paramValidator(
@ParamValidator(isRequired = true, desc = "年级", range = "int:1~9", message = "年级只能从1-9")
@RequestParam(name = "grade", required = true)
int grade,
@ParamValidator(isRequired = true, desc = "班级", range = "int:1~99", message = "班级只能从1-99")
@RequestParam(name = "classroom", required = true)
int classroom) {
return classroomService.getTeacherName(grade, classroom);
}
另外不要忘记方法二
里面里面提到的MethodValidationPostProcessor
这个bean,如果没有初始化这个bean,自定义的验证方法也不会执行。验证逻辑会失效。
是不是通过这样写注解的方式来验证进行请求的参数,代码逻辑更佳清晰和优雅?表达的含义也会更佳清楚?并且没有了大量重复的类似的验证代码。
Ps:这里的代码都是基于spring-mvc框架来试验的,如果有人并没有使用spring-mvc作为rest框架,而是使用jersey来作为rest框架的话,可能一些细节方面需要调整, 但是这三种方案应该都是可以兼容的。
作者:LOC_Thomas 链接:http://www.jianshu.com/p/2c2da2adef81 來源:简书 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
相关推荐
使用hibernate-validator 进行校验的jar包,里面包括了基础hibernate-validator-5.0.0.CR2.jar hibernate-validator-annotation-processor-5.0.0.CR2.jar 之外,还包括了el-api-2.2.jar javax.el-2.2.4等项目必不可...
Hibernate Validator 是一个基于 Bean Validation 规范的实现,是 Hibernate 项目的一部分,主要用于进行 Java 对象的验证。它提供了丰富的约束注解和自定义验证逻辑,使得开发者能够在 Java 应用程序中轻松地进行...
spring-cloud-starter-gateway下的依赖hibernate-validator-5.0.3.Final.jar
`hibernate-validator-4.1.0.Final.jar`是核心库,包含了所有验证相关的类和接口,供项目中直接引用使用。 6. **Sources.jar**: `hibernate-validator-4.1.0.Final-sources.jar`包含了源代码,开发者可以查看...
Hibernate.jar包,Hibernate可以应用在任何使用JDBC的场合,包含 hibernate-commons-annotations-4.0.1.Final.jar hibernate-core-4.1.12.Final.jar hibernate-ehcache-4.1.12....hibernate-validator-5.0.1.Final.jar
java运行依赖jar包
本主题将详细讲解`Hibernate Validator`以及与之相关的`validation-api-2.0.1.Final.jar`、`hibernate-validator-6.0.8.Final.jar`和`jboss-logging-3.3.2.Final.jar`这三个jar包的作用和重要性。 首先,`...
这是数据校验的jar包,使用了hibernate框架的部分功能,上传上来以方便博客里面进行引用...需要用的朋友也可以下载使用
hibernate-validator-4.2.0.Final.jar的下载
java运行依赖jar包
hibernate-validator-4.0.0.Beta1.jar
Hibernate Validator 是基于 JSR-303(Java Bean Validation)和 JSR-349(Java Bean Validation 1.1)规范的实现,它提供了一套灵活且强大的验证API,使得开发者能够对对象属性进行校验,确保输入数据的正确性。...
hibernate-validator-5.2.2.Final.jar , 供大家使用
hibernate-validator相关依赖jar包,包括jboss-logging-3.1.0.CR2.jar,hibernate-validator-4.3.1.Final.jar,validation-api-1.0.0.GA.jar
hibernate-validator-4.3.1.Final.jar jsr 303
hibernate-validator-6.0.14.Final.jar
hibernate-validator-6.0.2.Final-dist hibernate-validator-6.0.2.Final-dist hibernate-validator-6.0.2.Final-dist
Hibernate Validator用Annotations 给类或者类的属性加上约束,在运行期...该框架是十分容易的(就像参考文档中宣称的那样),几乎没有什么学习曲线,Validator 是一个验证框架 不需要和Hibernate的其他部分绑定就可以使用
Hibernate Validator,作为Java Bean Validation框架的实现,是Hibernate组织提供的一款强大的验证工具。本文将深入探讨Hibernate Validator 4.0.0.CR1版本,揭示其核心特性和实际应用。 一、Hibernate Validator...