搜索词>>validate 耗时0.0540
  • Spring Boot validation整合hibernate validator实现数据验证

    Spring Boot validation整合hibernate validator实现数据验证,Spring Boot validation使用说明,Spring Boot validation使用教程<h2>引言</h2>     这里主要讲解在Spring  Boot项目中整合hibernate validator框架实现Spring  Boot项目的validation 验证机制。方便后端验证前端或者接口传递过来的数据格式是否正确。 <h2>一.准备环境</h2> <ul> <li>jdk1.8+(Spring Boot项目推荐使用1.8)</li> <li>eclipse(或者你喜欢的IDE)</li> <li>maven 3+</li> </ul> <h2>二.编码实现Spring Boot validation</h2> <h3>2.1创建一个spring boot项目并添web模块和validation模块</h3> 项目结构图如下:<br /> <img srcset="" width="" size="" class="img-thumbnail" alt="spring boot项目结果图" src="/resources/assist/images/blog/017be0b2e4e848cb9bc98279929d073a.png" /><br /> 项目的依赖文件: <pre> <code class="language-xml"><?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>net.xqlee.project.demo</groupId> <artifactId>demo-springboot-hibernate-validator</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>demo-springboot-hibernate-validator</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>1.5.8.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter- </artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project> </code></pre> <h3> </h3> <blockquote> <h3>注意:</h3> <pre> <code class="language-xml"> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency></code></pre> 该模块会自动加载hibernate-validation依赖。不要自己手动配置谨防依赖问题</blockquote> <h3><br /> 2.2编写一个测试的简单对象POJO</h3> <pre> <code class="language-java">package net.xqlee.project.demo.pojo; import javax.validation.constraints.Pattern; import org.hibernate.validator.constraints.Length; import org.hibernate.validator.constraints.NotBlank; import org.hibernate.validator.constraints.NotEmpty; import org.hibernate.validator.constraints.Range; public class User { @NotBlank(message = "用户名称不能为空。") private String name; @Range(max = 150, min = 1, message = "年龄范围应该在1-150内。") private Integer age; @NotEmpty(message = "密码不能为空") @Length(min = 6, max = 8, message = "密码长度为6-8位。") @Pattern(regexp = "[a-zA-Z]*", message = "密码不合法") private String 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; } } </code></pre> 细心的朋友可能已经发现一些属性上的注解。验证框架正是实现了这些注解的具体验证。hibernate在java的JSR-303标准上还添加了一些额外的验证注解实现。这些实现都为我们后端验证数据取得了巨大的方便。 <blockquote> <p>提示:<br /> 验证注解推荐使用</p> <p>javax.validation.constraints包下的注解,不要使用hibernate的<br /> 在2.0中hibernate的很多注解已经弃用,但是</p> <p>javax.validation.constraints包下的注解增多增强<br /> 一种规范性的趋势</p> </blockquote> <h3>2.3编写一个controller用于测试验证机制</h3> <pre> <code class="language-java">package net.xqlee.project.demo.controller; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.validation.BindingResult; import org.springframework.validation.ObjectError; import org.springframework.validation.annotation.Validated; import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; import net.xqlee.project.demo.pojo.User; @RestController public class ValidatorController { private static final Logger log = LoggerFactory.getLogger(ValidatorController.class); /** * 验证框架使用测试 * * @param user * @param result */ @PostMapping("v/t1.json") public void v1(@Validated User user, BindingResult result) { StringBuilder sBuilder = new StringBuilder(); sBuilder.append("\n"); if (result.hasErrors()) { List<ObjectError> list = result.getAllErrors(); for (ObjectError error : list) { log.info(error.getCode() + "---" + error.getArguments() + "---" + error.getDefaultMessage()); sBuilder.append(error.getDefaultMessage()); sBuilder.append("\n"); } } log.info(sBuilder.toString()); } } </code></pre> <blockquote> <p>提示:<br /> @Validated (org.springframework.validation.annotation)<br /> 或者@Valid(javax.validation)<br /> 验证注解推荐写在方法的参数列表中,例如:<br /> Object   methodName(@Valid Object params){...}<br /> Object   methodName(@Validated Object params){...}<br /> <br />  </p> </blockquote> <h2><br /> 三.演示</h2> <h3>3.1启动spring boot项目</h3> <h3>3.2通过工具postmain进行提交数据验证</h3> <strong>第一组测试:</strong><br /> <br /> 提交全部为空数据:<br /> <img srcset="" width="" size="" class="img-thumbnail" alt="spring boot validation测试数据1" src="/resources/assist/images/blog/8d1b26436c0f42b382e4aa7378e4c466.png" /><br /> 观察eclipse的控制台输出:<br /> <img srcset="" width="" size="" class="img-thumbnail" alt="Spring Boot validation 控制台输出1" src="/resources/assist/images/blog/6b5e924b8c57446ab125be2043cec0e3.png" /><br /> 可以看到非空验证已经实现。<br /> <br /> <strong>第二组测试:</strong><br /> <br /> 接下来输入一个非空的名称和密码<br /> <img srcset="" width="" size="" class="img-thumbnail" alt="spring boot validation测试数据2" src="/resources/assist/images/blog/d86badcd7bc44cdba5080e8f87406023.png" /><br /> 观察eclipse控制台:<br /> <img srcset="" width="" size="" class="img-thumbnail" alt="Spring Boot validation 控制台输出2" src="/resources/assist/images/blog/87f994b3a6eb4bf9a77f3ce652471c11.png" /><br /> 可以看到名称的验证错误信息已经没有说明已经输入正确。但是密码却没有通过正则表达式的验证所以报错不合法,在对象上我们设置的密码只能是大写的字母。所以刚才输入的全数字不合法。<br /> <br /> <strong>第三组测试:</strong><br /> <br /> 接下来输入正常的密码<br /> <img srcset="" width="" size="" class="img-thumbnail" alt="spring boot validation测试数据3" src="/resources/assist/images/blog/40be7f44b6144ade956b3453ae420766.png" />观察控制台:<br /> <br /> <img srcset="" width="" size="" class="img-thumbnail" alt="Spring Boot validation 控制台输出3" src="/resources/assist/images/blog/2be73b7acb544f22845efacbb9c58a6f.png" /><br /> 可以看到已经没有错误信息。验证通过
  • hibernate validator 正则表达式报错javax.validation.constraints.Pattern

    hibernate validator 正则表达式报错HV000030: No validator could be found for constraint 'javax.validation.constraints.Pattern' validating type 'java.lang.Integer'.HV000030: No validator could be found for constraint 'javax.validation.constraints.Pattern' validating type 'java.lang.Integer'.
  • hibernate validate 手动验证集合/验证树形类结构

    hibernate validate 手动验证集合/验证树形类结构hibernate validate 手动验证
  • Spring Boot 2.0 hibernate validate 版本冲突导致严重失效

    Spring Boot 2.0 hibernate validate 版本冲突导致验证无效,HV000030: No validator could be found for constraint 'javax.validation.constraints.NotEmpty' validating type 'java.lang.String'. Check configuration forHV000030: No validator could be found for constraint 'javax.validation.constraints.NotEmpty' validating type 'java.lang.String'. Check configuration for 'parameter.applyNo'"
  • Spring Boot 2.0 hibernate validate List 验证

    Spring Boot 2.0 hibernate validate List 验证Spring Boot 2.0 hibernate validate List 验证
  • Java Bean Validation 2.0的方法约束 Java自定义验证注解

    在本文中,我们将讨论如何使用Bean Validation 2.0(JSR-380)定义和验证方法约束。在前面的文章中,我们讨论了JSR-380及其内置的注释,以及如何实现属性验证。在这里,我们将重点讨论不同类型的方法约束,例如:<h2 style="margin-left:0px; margin-right:0px; text-align:start"><strong>1.概述</strong></h2> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">在本文中,我们将讨论如何使用Bean Validation 2.0(JSR-380)定义和验证方法约束。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">在前面的文章中(<a rel="" target="_blank"href="http://www.leftso.com/blog/389.html" rel="" style="box-sizing:border-box; color:#63b175; text-decoration:none" target="_blank">Java Bean 基础验证</a>),我们讨论了JSR-380及其内置的注释,以及如何实现属性验证。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">在这里,我们将重点讨论不同类型的方法约束,例如:</span></span></span></p> <ul style="list-style-type:disc"> <li>单参数约束</li> <li>交叉<strong>复杂</strong>参数(自定义Java Bean验证注解)</li> <li>返回约束</li> </ul> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">另外,我们将看看如何使用Spring Validator手动和自动验证约束。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="font-family:raleway"><span style="background-color:#ffffff">对于以下示例,我们需要与<a rel="" target="_blank"href="http://www.leftso.com/blog/389.html" rel="" style="box-sizing:border-box; color:#63b175; text-decoration:none" target="_blank">Java Bean验证基础中</a>完全相同的依赖关系 。</span></span><br />  </p> <h2 style="margin-left:0px; margin-right:0px; text-align:start"><strong>2.方法约束声明</strong></h2> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">首先,<strong>我们将首先讨论如何声明方法参数的约束和方法返回的值</strong>。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">如前所述,我们可以使用来自<em>javax.validation.constraints的注解</em>  ,但我们也可以指定自定义约束(例如,对于自定义约束或交叉参数约束)。</span></span></span></p> <h3 style="margin-left:0px; margin-right:0px; text-align:start"><strong>2.1。单参数约束</strong></h3> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">定义单个参数的限制很简单。<strong>我们只需要根据需要为每个参数添加注解</strong>:</span></span></span></p> <pre> <code class="language-java">public void createReservation(@NotNull @Future LocalDate begin, @Min(1) int duration, @NotNull Customer customer) { // ... }</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">同样,我们可以对构造函数使用相同的方法:</span></span></span></p> <div style="text-align:start"> <div style="margin-left:0px; margin-right:0px"> <pre> <code class="language-java">public class Customer { public Customer(@Size(min = 5, max = 200) @NotNull String firstName, @Size(min = 5, max = 200) @NotNull String lastName) { this.firstName = firstName; this.lastName = lastName; } // properties, getters, and setters }</code></pre> </div> </div> <h3 style="margin-left:0px; margin-right:0px; text-align:start"><strong>2.2。使用交叉复杂参数约束</strong></h3> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">在某些情况下,我们可能需要一次验证多个值,例如,两个数值比另一个大一些。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">对于这些场景,我们可以定义自定义跨参数约束,这可能取决于两个或更多参数。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff"><strong>交叉参数约束可以被认为是等同于类级约束的方法验证</strong>。我们可以使用两者来基于多个属性来实现验证。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">让我们考虑一个简单的例子:上一节中的<em>createReservation()</em>方法的变体  接受两个<em>LocalDate</em>类型的参数<em>:</em>  开始日期和结束日期。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">因此,我们要确保<em>开始</em>是在未来,<em>结束</em>是在<em>开始</em>之后。与前面的例子不同,我们不能用单个参数约束来定义它。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">相反,我们需要一个交叉参数约束。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">与单参数约束相反,<strong>交叉参数约束在方法或构造函数中声明</strong>:</span></span></span></p> <pre> <code class="language-java">@ConsistentDateParameters public void createReservation(LocalDate begin, LocalDate end, Customer customer) { // ... }</code></pre> <h3 style="margin-left:0px; margin-right:0px; text-align:start"><strong>2.3。创建交叉参数约束</strong></h3> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">要实现<em>@ConsistentDateParameters</em>约束,我们需要两个步骤。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">首先,我们需要<strong>定义约束注解</strong>:</span></span></span></p> <pre> <code class="language-java">@Constraint(validatedBy = ConsistentDateParameterValidator.class) @Target({ METHOD, CONSTRUCTOR }) @Retention(RUNTIME) @Documented public @interface ConsistentDateParameters { String message() default "End date must be after begin date and both must be in the future"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">这里,这三个属性对于约束注释是强制性的:</span></span></span></p> <ol> <li><strong>message</strong><em>- </em>返回创建错误消息的默认密钥,这使我们能够使用消息插值</li> <li><strong>groups</strong>   - 允许我们为约束指定验证组</li> <li><strong>payload </strong> - 可由Bean Validation API的客户端使用,以将自定义有效载荷对象分配给约束</li> </ol> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">有关如何定义自定义约束的详细信息,请查看  <a href="https://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#validator-customconstraints" rel="external nofollow" style="box-sizing:border-box; color:#63b175; text-decoration:none" target="_blank">官方文档</a>。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">之后,我们可以定义验证器类:</span></span></span></p> <pre> <code class="language-java">@SupportedValidationTarget(ValidationTarget.PARAMETERS) public class ConsistentDateParameterValidator implements ConstraintValidator<ConsistentDateParameters, Object[]> { @Override public boolean isValid( Object[] value, ConstraintValidatorContext context) { if (value[0] == null || value[1] == null) { return true; } if (!(value[0] instanceof LocalDate) || !(value[1] instanceof LocalDate)) { throw new IllegalArgumentException( "Illegal method signature, expected two parameters of type LocalDate."); } return ((LocalDate) value[0]).isAfter(LocalDate.now()) && ((LocalDate) value[0]).isBefore((LocalDate) value[1]); } }</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">正如我们所看到的,<em>isValid() </em>方法包含实际的验证逻辑。首先,我们确保我们得到两个类型为<em>LocalDate的</em>参数<em>。</em> 之后,我们检查两者是否在未来,<em>结束</em>是在<em>开始</em>之后。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">此外,值得注意的是,很重要  <em>@SupportedValidationTarget(ValidationTarget <strong>。</strong>参数)</em>的注解  <em>ConsistentDateParameterValidator</em>类是必需的。原因是因为  <em>@ConsistentDateParameter</em>  是在方法级别上设置的,但是约束条件应该应用于方法参数(而不是方法的返回值,我们将在下一节讨论)。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">注意:Bean验证规范建议将<em>空值</em>视为有效。如果<em>null</em>不是有效值,则应该使用<em>@NotNull</em> -annotation。</span></span></span></p> <h3 style="margin-left:0px; margin-right:0px; text-align:start"><strong>2.4。返回值约束</strong></h3> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff"><strong>有时我们需要验证一个对象,因为它是由方法返回的。为此,我们可以使用返回值约束。</strong></span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">以下示例使用内置约束:</span></span></span></p> <pre> <code class="language-java">public class ReservationManagement { @NotNull @Size(min = 1) public List<@NotNull Customer> getAllCustomers() { return null; } }</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">对于<em>getAllCustomers()</em>,以下约束条件适用:</span></span></span></p> <ul style="list-style-type:disc"> <li>首先,返回的列表不能为<em>空,</em>且必须至少有一个条目</li> <li>此外,该列表不能包含<em>空</em>条目</li> </ul> <h3 style="margin-left:0px; margin-right:0px; text-align:start"><strong>2.5。返回值自定义约束</strong></h3> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">在某些情况下,我们可能还需要验证复杂的对象:</span></span></span></p> <pre> <code class="language-java">public class ReservationManagement { @ValidReservation public Reservation getReservationsById(int id) { return null; } }</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">在这个例子中,返回的<em>Reservation</em>  对象必须满足由<em>@ValidReservation</em>定义的约束,我们将在下面定义它。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">再次,<strong>我们首先必须定义约束注释</strong>:</span></span></span></p> <pre> <code class="language-java">@Constraint(validatedBy = ValidReservationValidator.class) @Target({ METHOD, CONSTRUCTOR }) @Retention(RUNTIME) @Documented public @interface ValidReservation { String message() default "End date must be after begin date " + "and both must be in the future, room number must be bigger than 0"; Class<?>[] groups() default {}; Class<? extends Payload>[] payload() default {}; }</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start">之后,我们定义类验证器:<br />  </p> <pre> <code class="language-java">public class ValidReservationValidator implements ConstraintValidator<ValidReservation, Reservation> { @Override public boolean isValid( Reservation reservation, ConstraintValidatorContext context) { if (reservation == null) { return true; } if (!(reservation instanceof Reservation)) { throw new IllegalArgumentException("Illegal method signature, " + "expected parameter of type Reservation."); } if (reservation.getBegin() == null || reservation.getEnd() == null || reservation.getCustomer() == null) { return false; } return (reservation.getBegin().isAfter(LocalDate.now()) && reservation.getBegin().isBefore(reservation.getEnd()) && reservation.getRoom() > 0); } }</code></pre> <h3 style="margin-left:0px; margin-right:0px; text-align:start"><strong>2.6。在构造函数中返回值</strong></h3> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">由于我们之前在我们的<em>ValidReservation</em>接口中定义了  <em>METHOD</em>和<em>CONSTRUCTOR</em>作为<em>目标</em>,<strong>我们也可以注释</strong><strong><em>Reservation</em></strong><strong>的构造函数</strong><strong>来验证构造的实例</strong>:</span></span></span></p> <pre> <code class="language-java">public class Reservation { @ValidReservation public Reservation( LocalDate begin, LocalDate end, Customer customer, int room) { this.begin = begin; this.end = end; this.customer = customer; this.room = room; } // properties, getters, and setters }</code></pre> <h3 style="margin-left:0px; margin-right:0px; text-align:start"><strong>2.7。级联验证</strong></h3> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">最后,Bean Validation API使我们不仅可以验证单个对象,还可以使用所谓的级联验证验证对象图。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff"><strong>因此,如果我们想验证复杂的对象,我们可以使用<em>@Valid</em>进行级联验证</strong>。这适用于方法参数以及返回值。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">假设我们有一个带有一些属性约束的<em>Customer</em>类:</span></span></span></p> <pre> <code class="language-java">public class Customer { @Size(min = 5, max = 200) private String firstName; @Size(min = 5, max = 200) private String lastName; // constructor, getters and setters }</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start">一个<em>预定</em>类可能有一个<em>客户</em>的财产,以及与约束进一步特性:</p> <pre> <code class="language-java">public class Reservation { @Valid private Customer customer; @Positive private int room; // further properties, constructor, getters and setters }</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start">如果我们现在引用<em>Reservation</em>作为方法参数,<strong>我们可以强制所有属性的递归验证</strong>:<br />  </p> <pre> <code class="language-java">public void createNewCustomer(@Valid Reservation reservation) { // ... }</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">我们可以看到,我们在两个地方使用<em>@Valid</em>:</span></span></span></p> <ul style="list-style-type:disc"> <li>在<em>保留</em>参数上:当<em>createNewCustomer()</em>被调用时,它触发<em>Reservation-</em> object 的验证</li> <li>由于我们在这里有一个嵌套的对象图,我们还必须在<em>customer- </em><em>attribute</em>上添加一个<em>@Valid</em>:因此,它会触发验证这个嵌套属性</li> </ul> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">这也适用于返回<em>预留</em>类型对象的方法  :</span></span></span></p> <div style="text-align:start"> <div style="margin-left:0px; margin-right:0px"> <pre> <code class="language-java">@Valid public Reservation getReservationById(int id) { return null; }</code></pre> </div> </div> <h2 style="margin-left:0px; margin-right:0px; text-align:start"><strong>3.验证方法约束</strong></h2> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">在上一节中声明约束之后,我们现在可以继续实际验证这些约束。为此,我们有多种方法。</span></span></span></p> <h3 style="margin-left:0px; margin-right:0px; text-align:start"><strong>3.1。使用Spring自动验证</strong></h3> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff"><strong>Spring Validation提供了与Hibernate Validator的集成。</strong></span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">注意:Spring验证基于AOP,并使用Spring AOP作为默认实现。因此,验证只适用于方法,但不适用于构造函数。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">如果我们现在希望Spring自动验证我们的约束,我们必须做两件事:</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff"><strong>首先,我们必须使用<em>@Validated</em></strong><strong>注释应该验证的  </strong><strong><em>bean</em></strong>:</span></span></span><br />  </p> <pre> <code class="language-java">@Validated public class ReservationManagement { public void createReservation(@NotNull @Future LocalDate begin, @Min(1) int duration, @NotNull Customer customer){ // ... } @NotNull @Size(min = 1) public List<@NotNull Customer> getAllCustomers(){ return null; } }</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start"><strong>其次,我们必须提供一个<em>MethodValidationPostProcessor</em> bean:</strong></p> <pre> <code class="language-java">@Configuration @ComponentScan({ "org.baeldung.javaxval.methodvalidation.model" }) public class MethodValidationConfig { @Bean public MethodValidationPostProcessor methodValidationPostProcessor() { return new MethodValidationPostProcessor(); } }</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">如果违反约束,容器现在将抛出  <em>javax.validation.ConstraintViolationException</em>。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">如果我们使用Spring Boot,只要<em>hibernate-validator</em>在类路径中,容器就会为我们注册一个  <em>MethodValidationPostProcessor </em> bean  。</span></span></span></p> <h3 style="margin-left:0px; margin-right:0px; text-align:start"><strong>3.2。CDI自动验证(JSR-365)</strong></h3> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">从版本1.1开始,Bean Validation与CDI(用于Java EE的上下文和依赖注入)协同工作。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">如果我们的应用程序在Java EE容器中运行,那么容器将在调用时自动验证方法约束。</span></span></span></p> <h3 style="margin-left:0px; margin-right:0px; text-align:start"><strong>3.3。程序化验证</strong></h3> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">对于  <strong>独立Java应用程序中的手动方法验证</strong>,我们可以使用  <em>javax.validation.executable.ExecutableValidator</em>接口。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">我们可以使用以下代码检索实例:</span></span></span></p> <pre> <code class="language-java">ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); ExecutableValidator executableValidator = factory.getValidator().forExecutables();</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">ExecutableValidator提供了四种方法:</span></span></span></p> <ul style="list-style-type:disc"> <li>用于方法验证的<em>validateParameters()</em>和<em>validateReturnValue()</em></li> <li>用于构造函数验证的<em>validateConstructorParameters()</em>和<em>validateConstructorReturnValue()</em></li> </ul> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">验证我们的第一个方法<em>createReservation()</em>的参数如下所示:</span></span></span></p> <pre> <code class="language-java">ReservationManagement object = new ReservationManagement(); Method method = ReservationManagement.class .getMethod("createReservation", LocalDate.class, int.class, Customer.class); Object[] parameterValues = { LocalDate.now(), 0, null }; Set<ConstraintViolation<ReservationManagement>> violations = executableValidator.validateParameters(object, method, parameterValues);</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff"><strong>注意:官方文档不鼓励直接从应用程序代码调用此接口,而是通过方法拦截技术(如AOP或代理)来使用它。</strong></span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">如果您有兴趣如何使用  <em>ExecutableValidator</em>接口,可以查看<a href="http://docs.jboss.org/hibernate/stable/validator/reference/en-US/html_single/#section-validating-executable-constraints" rel="external nofollow" style="box-sizing:border-box; color:#63b175; text-decoration:none" target="_blank">官方文档</a>。</span></span></span></p> <h2 style="margin-left:0px; margin-right:0px; text-align:start"><strong>4。总结</strong></h2> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">在本教程中,我们快速浏览了如何使用Hibernate Validator的方法约束,同时我们还讨论了JSR-380的一些新功能。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">首先,我们讨论了如何声明不同类型的约束:</span></span></span></p> <ul style="list-style-type:disc"> <li>单参数约束</li> <li>跨参数</li> <li>返回值约束</li> </ul> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">我们还看了如何使用Spring Validator手动和自动验证约束。</span></span></span></p>
  • Spring Boot 2.0 REST API 接口的数据验证

    在本Spring boot教程中,我们将学习如何验证发送到PUT/POST API请求的数据BODY。我们还将学习在API响应中添加自定义错误消息以提示错误。<h2>1.概要</h2> <blockquote> <p>在本Spring boot教程中,我们将学习如何验证发送到PUT/POST API请求的数据BODY。我们还将学习<strong>在API响应中添加自定义错误消息</strong>以提示错误。</p> </blockquote> 在这个演示中,我们将主要看到两个主要的验证案例 - <ol> <li>HTTP POST <code>/employees</code>和请求正文不包含有效值或缺少一些字段。它将在响应主体中返回带有适当消息的HTTP状态代码400。</li> <li><code>/employees/{id}</code>请求中会发送HTTP GET 和INVALID ID。它会在响应主体中返回HTTP状态码404和正确的消息。</li> </ol> <h2 style="margin-left:0px; margin-right:0px; text-align:start">2.创建REST 模型和API类</h2> <strong>EmployeeVO.java</strong> <pre> <code class="language-java">@XmlRootElement(name = "employee") @XmlAccessorType(XmlAccessType.FIELD) public class EmployeeVO extends ResourceSupport implements Serializable { private Integer employeeId; private String firstName; private String lastName; private String email; public EmployeeVO(Integer id, String firstName, String lastName, String email) { super(); this.employeeId = id; this.firstName = firstName; this.lastName = lastName; this.email = email; } public EmployeeVO() { } //Removed setter/getter for readability }</code></pre> <strong>EmployeeRESTController.java</strong> <pre> <code class="language-java">@PostMapping(value = "/employees") public ResponseEntity<EmployeeVO> addEmployee (@RequestBody EmployeeVO employee) { EmployeeDB.addEmployee(employee); return new ResponseEntity<EmployeeVO>(employee, HttpStatus.OK); } @GetMapping(value = "/employees/{id}") public ResponseEntity<EmployeeVO> getEmployeeById (@PathVariable("id") int id) { EmployeeVO employee = EmployeeDB.getEmployeeById(id); if(employee == null) { throw new RecordNotFoundException("Invalid employee id : " + id); } return new ResponseEntity<EmployeeVO>(employee, HttpStatus.OK); }</code></pre> <h2 style="margin-left:0px; margin-right:0px; text-align:start">3.应用请求验证和异常处理</h2> 默认请求支持spring的验证<br /> 要应用默认验证,您只需在适当的位置添加相关注解。即<br /> <br /> <strong>使用所需的验证特定注释来注释模型类</strong> <pre> <code class="language-java">@XmlRootElement(name = "employee") @XmlAccessorType(XmlAccessType.FIELD) public class EmployeeVO extends ResourceSupport implements Serializable { private static final long serialVersionUID = 1L; public EmployeeVO(Integer id, String firstName, String lastName, String email) { super(); this.employeeId = id; this.firstName = firstName; this.lastName = lastName; this.email = email; } public EmployeeVO() { } private Integer employeeId; @NotEmpty(message = "first name must not be empty") private String firstName; @NotEmpty(message = "last name must not be empty") private String lastName; @NotEmpty(message = "email must not be empty") @Email(message = "email should be a valid email") private String email; //Removed setter/getter for readability }</code></pre> <br /> <strong>通过@Valid注释启用对请求主体的验证</strong> <h4 style="margin-left:0px; margin-right:0px; text-align:start">自定义验证以添加有意义的信息</h4> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#333333"><span style="font-family:"varela round",sans-serif"><span style="background-color:#ffffff">默认的弹簧验证工作,并提供有关错误的信息超载,这就是为什么你应该根据你的应用程序的需要定制它。您只能提供所需的错误信息,并且语句非常清晰。额外的信息也不建议。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#333333"><span style="font-family:"varela round",sans-serif"><span style="background-color:#ffffff">建立有意义的例外并且足够好地描述问题始终是一个很好的建议。一种方法是创建单独的类来表示特定的业务用例失败,并在该用例失败时返回它们。</span></span></span></p> 例如,我已经<code>RecordNotFoundException</code>为所有buch场景创建了一个类,在这个场景中,资源被其ID所请求,并且系统中找不到资源。 <pre> <code class="language-java"> import org.springframework.http.HttpStatus; import org.springframework.web.bind.annotation.ResponseStatus; @ResponseStatus(HttpStatus.NOT_FOUND) public class RecordNotFoundException extends RuntimeException { public RecordNotFoundException(String exception) { super(exception); } }</code></pre> 同样,我写了一个特殊的类,它将被返回所有失败案例。为所有API提供一致的错误消息结构,帮助API消费者编写更健壮的代码 <pre> <code class="language-java">import java.util.List; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "error") public class ErrorResponse { public ErrorResponse(String message, List<String> details) { super(); this.message = message; this.details = details; } //General error message about nature of error private String message; //Specific errors in API request processing private List<String> details; //Getter and setters }</code></pre> 现在添加一个类,<code>ResponseEntityExceptionHandler</code>并使用注释对其进行<code>@ControllerAdvice注解</code>。<code>ResponseEntityExceptionHandler</code>是一个方便的基类,<code>@RequestMapping</code>通过<code>@ExceptionHandler</code>方法提供跨所有方法的集中式异常处理。<code>@ControllerAdvice</code>更适用于在应用程序启动时启用自动扫描和配置。<br /> <strong>CustomExceptionHandler.java</strong> <pre> <code class="language-java">import java.util.ArrayList; import java.util.List; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; import org.springframework.validation.ObjectError; import org.springframework.web.bind.MethodArgumentNotValidException; import org.springframework.web.bind.annotation.ControllerAdvice; import org.springframework.web.bind.annotation.ExceptionHandler; import org.springframework.web.context.request.WebRequest; import org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler; @SuppressWarnings({"unchecked","rawtypes"}) @ControllerAdvice public class CustomExceptionHandler extends ResponseEntityExceptionHandler { @ExceptionHandler(Exception.class) public final ResponseEntity<Object> handleAllExceptions(Exception ex, WebRequest request) { List<String> details = new ArrayList<>(); details.add(ex.getLocalizedMessage()); ErrorResponse error = new ErrorResponse("Server Error", details); return new ResponseEntity(error, HttpStatus.INTERNAL_SERVER_ERROR); } @ExceptionHandler(RecordNotFoundException.class) public final ResponseEntity<Object> handleUserNotFoundException(RecordNotFoundException ex, WebRequest request) { List<String> details = new ArrayList<>(); details.add(ex.getLocalizedMessage()); ErrorResponse error = new ErrorResponse("Record Not Found", details); return new ResponseEntity(error, HttpStatus.NOT_FOUND); } @Override protected ResponseEntity<Object> handleMethodArgumentNotValid(MethodArgumentNotValidException ex, HttpHeaders headers, HttpStatus status, WebRequest request) { List<String> details = new ArrayList<>(); for(ObjectError error : ex.getBindingResult().getAllErrors()) { details.add(error.getDefaultMessage()); } ErrorResponse error = new ErrorResponse("Validation Failed", details); return new ResponseEntity(error, HttpStatus.BAD_REQUEST); } }</code></pre> 以上类处理各种异常情况,包括<code>RecordNotFoundException</code>:它还处理<code>@RequestBody</code>注释对象中的请求验证错误。让我们看看它是如何工作的。 <h2 style="margin-left:0px; margin-right:0px; text-align:start">请求验证演示</h2> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#333333"><span style="font-family:"varela round",sans-serif"><span style="background-color:#ffffff">1)HTTP GET / employees / 1 [有效]</span></span></span></p> <pre> <code class="language-html">HTTP Status : 200 { "employeeId": 1, "firstName": "firstName", "lastName": "lastName", "email": "email@gamil.com", }</code></pre> <img srcset="" width="" size="" class="img-thumbnail" alt="测试请求1" src="/resources/assist/images/blog/1718c58a8bf6482d9a94503d373f8dcd.jpg" /><br /> 2)HTTP GET / employees / 23 [INVALID] <pre> <code class="language-html">HTTP Status : 404 { "message": "Record Not Found", "details": [ "Invalid employee id : 23" ] }</code></pre> <img srcset="" width="" size="" class="img-thumbnail" alt="输入错误的ID号查询" src="/resources/assist/images/blog/6f8285e95e7d4401b4216738fcfda70a.png" /><br /> 3)HTTP POST / employees [INVALID] <pre> <code class="language-html">请求参数: { "lastName": "Bill", "email": "ibill@gmail.com" }</code></pre> <pre> <code class="language-html">响应结果: HTTP Status : 400 { "message": "Validation Failed", "details": [ "first name must not be empty" ] }</code></pre> <img srcset="" width="" size="" class="img-thumbnail" alt="数据测试三" src="/resources/assist/images/blog/11f830ebd7cc47b0ba74d5dd0c17479f.png" /><br /> 4)HTTP POST / employees [INVALID] <pre> <code class="language-html">请求参数: { "email": "ibill@gmail.com" }</code></pre> <pre> <code class="language-html">响应结果: HTTP Status : 400 { "message": "Validation Failed", "details": [ "last name must not be empty", "first name must not be empty" ] }</code></pre> <img srcset="" width="" size="" class="img-thumbnail" alt="测试结果4" src="/resources/assist/images/blog/814a48b35b444282ab6d4ee946d5c932.png" /><br /> 5)HTTP POST / employees [INVALID] <pre> <code class="language-html">请求参数: { "firstName":"Lokesh", "email": "ibill_gmail.com" //invalid email in request }</code></pre> <pre> <code>响应内容: HTTP Status : 400 { "message": "Validation Failed", "details": [ "last name must not be empty", "email should be a valid email" ] }</code></pre> <h2 style="margin-left:0px; margin-right:0px; text-align:start"><img srcset="" width="" size="" class="img-thumbnail" alt="测试结果5" src="/resources/assist/images/blog/1b67c3cab6ef4259a58a544d5d164752.png" /><br /> 可用的注解</h2> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#333333"><span style="font-family:"varela round",sans-serif"><span style="background-color:#ffffff">在上面的例子中,我们只使用了几个注释,如<code>@NotEmpty</code>和<code>@Email</code>。还有更多这样的注释来验证请求数据。需要时检查出来。</span></span></span></p> <table class="table table-bordered table-hover" > <tbody> <tr> <th>注解</th> <th>使用说明</th> </tr> <tr> <td>@AssertFalse</td> <td>注释的元素必须是false。</td> </tr> <tr> <td>@AssertTrue</td> <td>注释的元素必须为true。</td> </tr> <tr> <td>@DecimalMax</td> <td>带注释的元素必须是其值必须小于或等于指定最大值的数字。</td> </tr> <tr> <td>@DecimalMin</td> <td>带注释的元素必须是其值必须高于或等于指定最小值的数字。</td> </tr> <tr> <td>@Future</td> <td>注释元素必须是未来的即时,日期或时间。</td> </tr> <tr> <td>@Max</td> <td>带注释的元素必须是其值必须小于或等于指定最大值的数字。</td> </tr> <tr> <td>@Min</td> <td>带注释的元素必须是其值必须高于或等于指定最小值的数字。</td> </tr> <tr> <td>@Negative</td> <td>带注释的元素必须是严格负数。</td> </tr> <tr> <td>@NotBlank</td> <td>带注释的元素不得<code>null</code>并且必须至少包含一个非空白字符。</td> </tr> <tr> <td>@NotEmpty</td> <td>带注释的元素不能<code>null</code>也不是空的。</td> </tr> <tr> <td>@NotNull</td> <td>注释的元素不能是<code>null</code>。</td> </tr> <tr> <td>@Null</td> <td>注释的元素必须是<code>null</code>。</td> </tr> <tr> <td>@Pattern</td> <td>注释的CharSequence必须与指定的正则表达式匹配。</td> </tr> <tr> <td>@Positive</td> <td>带注释的元素必须是严格的正数。</td> </tr> <tr> <td>@Size</td> <td>注释的元素大小必须在指定的边界之间(包含)。</td> </tr> </tbody> </table>   <h2><strong>总结</strong></h2> spring boot <strong>REST验证教程中</strong>,我们学到了 - <ol> <li>通过ID获取资源时验证ID。</li> <li>验证POST / PUT API中的请求主体字段。</li> <li>在API响应中发送一致且结构化的错误响应。</li> </ol> <blockquote> <p>提示:<a href="http://www.leftso.com/resource/1010.html" target="_blank" >项目源码下载</a></p> </blockquote>
  • Java Bean 基础验证

    在这篇快速文章中,我们将介绍使用标准框架 - JSR 380(也称为Bean Validation 2.0)来验证Java bean的基础知识。当然,在大多数应用程序中验证用户输入是超常见的需求,而Java Bean验证框架已成为处理这种逻辑的事实上的标准。<h2 style="margin-left:0px; margin-right:0px; text-align:start"><strong>1.概述</strong></h2> <blockquote> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway">在这篇快速文章中,我们将<strong>介绍</strong>使用标准框架 - JSR 380(也称为<em>Bean Validation 2.0)</em><strong>来验证Java bean的基础知识</strong><em>。</em></span></span><br /> <span style="color:#535353"><span style="font-family:raleway">当然,在大多数应用程序中验证用户输入是超常见的需求,而Java Bean验证框架已成为处理这种逻辑的事实上的标准。</span></span></p> </blockquote> <h2 style="margin-left:0px; margin-right:0px; text-align:start"><strong>2. JSR 380</strong></h2> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">JSR 380是用于Bean验证,JavaEE的和的JavaSE的一部分,这确保了一个bean的属性符合特定条件,使用注释如Java API的说明书中<em>@NotNull</em>,<em>@Min</em>,和  <em>@Max</em>。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">该版本需要Java 8或更高版本,并利用Java 8中添加的新功能(例如类型注释),并支持新类型(如<em>Optional</em>和<em>LocalDate)</em>。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">有关规格的完整信息,请继续阅读<a href="https://jcp.org/en/jsr/detail?id=380" rel="external nofollow" style="box-sizing:border-box; color:#63b175; text-decoration:none" target="_blank">JSR 380</a>。</span></span></span><br />  </p> <h2 style="margin-left:0px; margin-right:0px; text-align:start"><strong>3.依赖性</strong></h2> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">我们将使用Maven示例来显示所需的依赖关系,但当然,可以使用各种方式添加这些jar。</span></span></span><br />  </p> <h3 style="margin-left:0px; margin-right:0px; text-align:start"><strong>3.1。验证API</strong></h3> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">根据JSR 380规范,<em>validation-api</em>依赖包含标准验证API:</span></span></span></p> <pre> <code class="language-xml"><dependency> <groupId>javax.validation</groupId> <artifactId>validation-api</artifactId> <version>2.0.0.Final</version> </dependency></code></pre>   <h3 style="margin-left:0px; margin-right:0px; text-align:start"><strong>3.2。验证API参考实现</strong></h3> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff"><strong>Hibernate Validator是验证API的参考实现。</strong></span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">要使用它,我们必须添加以下依赖项:</span></span></span></p> <pre> <code class="language-xml"><dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator</artifactId> <version>6.0.2.Final</version> </dependency> <dependency> <groupId>org.hibernate.validator</groupId> <artifactId>hibernate-validator-annotation-processor</artifactId> <version>6.0.2.Final</version> </dependency></code></pre> 这里的一个快速提示:<strong><em>hibernate-validator</em>完全独立于Hibernate的持久化方面功能模块,</strong>并且通过添加它作为依赖项,我们不会将这些持久性方面功能模块添加到项目中。<br />   <h3 style="margin-left:0px; margin-right:0px; text-align:start"><strong>3.3。表达式语言依赖关系</strong></h3> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">JSR 380提供了对变量插值的支持,允许违规消息中的表达式。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">要解析这些表达式,我们必须添加对表达式语言API和该API实现的依赖关系。GlassFish提供了参考实现:</span></span></span></p> <pre> <code class="language-xml"><dependency> <groupId>javax.el</groupId> <artifactId>javax.el-api</artifactId> <version>3.0.0</version> </dependency> <dependency> <groupId>org.glassfish.web</groupId> <artifactId>javax.el</artifactId> <version>2.2.6</version> </dependency></code></pre> 如果未添加这些JAR,则会在运行时收到错误消息,如下所示: <blockquote> <p><em>HV000183: Unable to load ‘javax.el.ExpressionFactory’. Check that you have the EL dependencies on the classpath, or use ParameterMessageInterpolator instead</em></p> </blockquote> <h2 style="margin-left:0px; margin-right:0px; text-align:start"><strong>4.使用验证注解</strong></h2> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">我们将在这里使用一个<em>用户</em> bean作为主要的例子,并且为它添加​​一些简单的验证:</span></span></span></p> <pre> <code class="language-java">import javax.validation.constraints.AssertTrue; import javax.validation.constraints.Max; import javax.validation.constraints.Min; import javax.validation.constraints.NotNull; import javax.validation.constraints.Size; import javax.validation.constraints.Email; public class User { @NotNull(message = "Name cannot be null") private String name; @AssertTrue private boolean working; @Size(min = 10, max = 200, message = "About Me must be between 10 and 200 characters") private String aboutMe; @Min(value = 18, message = "Age should not be less than 18") @Max(value = 150, message = "Age should not be greater than 150") private int age; @Email(message = "Email should be valid") private String email; // standard setters and getters }</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">示例中使用的所有注释都是标准的JSR注释:</span></span></span></p> <ul style="list-style-type:disc"> <li><strong><em>@NotNull</em></strong> - 验证注释的属性值不为 <em> null</em></li> <li><strong><em>@AssertTrue</em></strong> - 验证注释的属性值是否为 <em>真</em></li> <li><strong><em>@Size </em></strong> - 验证注释的属性值的大小在属性<em> min</em>和<em> max之间</em> ; 可以应用于 <em> String</em>, <em> Collection</em>, <em> Map</em>和数组属性</li> <li><strong><em>@Min </em></strong> -<em>  v</em>验证注释的属性的值不小于<em>值 </em>属性</li> <li><strong><em>@Max </em></strong> - 验证注释的属性的值不大于<em>值</em>属性</li> <li><em><strong>@电子邮件</strong></em> - 验证注释的属性是一个有效的电子邮件地址</li> </ul> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">一些注释接受附加属性,但是<em>消息</em>属性对所有属性都是通用的。这是当相应属性的值未通过验证时通常会显示的消息。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">JSR中可以找到的一些附加注释是:</span></span></span></p> <ul style="list-style-type:disc"> <li><em><strong>@NotEmpty</strong></em> - 验证该属性不为空或空; 可以应用于<em> String</em>,<em> Collection</em>,<em> Map</em>或<em> Array</em>值</li> <li><em><strong>@NotBlank</strong></em> - 只能应用于文本值并验证属性不为空或空白</li> <li><em><strong>@Positive</strong></em>和<em><strong> @PositiveOrZero</strong></em> - 适用于数值并验证它们是严格正数,还是正数,包括0</li> <li><em><strong>@Negative</strong></em>和<em><strong> @NegativeOrZero</strong></em> - 应用于数字值并验证它们是严格否定的,或者是否定的,包括0</li> <li><em><strong>@Past</strong></em>和<em><strong> @PastOrPresent</strong></em> - 验证日期值是过去还是过去,包括现在; 可以应用于日期类型,包括在Java 8中添加的日期类型</li> <li><em><strong>@Future</strong>和<strong>@FutureOrPresent</strong></em> - 验证日期值是未来还是未来,包括现在</li> </ul> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff"><strong>验证注释也可以应用于集合的元素</strong>:</span></span></span></p> <pre> <code class="language-java">List<@NotBlank String> preferences;</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">在这种情况下,任何添加到首选项列表的值都将被验证。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">规范<strong>还支持</strong> Java 8中<strong>的新的</strong><strong><em>可选</em></strong><strong>类型</strong>:</span></span></span></p> <pre> <code class="language-java">private LocalDate dateOfBirth; public Optional<@Past LocalDate> getDateOfBirth() { return Optional.of(dateOfBirth); }</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">在这里,验证框架将自动解包<em>LocalDate </em>值并对其进行验证。</span></span></span></p> <h2 style="margin-left:0px; margin-right:0px; text-align:start"><strong>5.程序化验证</strong></h2> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">一些框架 - 比如Spring--通过使用注释可以简单地触发验证过程。这主要是因为我们不必与编程验证API进行交互。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">现在让我们开始手动路线并以编程方式设置:</span></span></span></p> <pre> <code class="language-java">ValidatorFactory factory = Validation.buildDefaultValidatorFactory(); Validator validator = factory.getValidator();</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">为了验证一个bean,我们必须首先有一个<em>Validator</em>对象,它是使用<em>ValidatorFactory</em>构造的  。</span></span></span></p> <h3 style="margin-left:0px; margin-right:0px; text-align:start"><strong>5.1。定义Bean</strong></h3> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">我们现在要设置这个无效的用户 - 具有空<em>名称</em>值:</span></span></span></p> <pre> <code class="language-java">User user = new User(); user.setWorking(true); user.setAboutMe("Its all about me!"); user.setAge(50);</code></pre> <h3 style="margin-left:0px; margin-right:0px; text-align:start"><strong>5.2。验证Bean</strong></h3> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">现在我们有了一个<em>Validator</em>,我们可以通过将它传递给<em>validate</em>方法来验证我们的bean 。任何违反<em>用户</em>对象中定义的约束条件  都将作为一个<em>Set</em>返回。</span></span></span></p> <pre> <code class="language-java">Set<ConstraintViolation<User>> violations = validator.validate(user);</code></pre> 通过遍历违规,我们可以通过使用<em>getMessage </em>方法来获取所有违规消息。 <pre> <code class="language-java">for (ConstraintViolation<User> violation : violations) { log.error(violation.getMessage()); }</code></pre> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">在我们的示例(<em>ifNameIsNull_nameValidationFails</em>)中,该集合将包含一个  <em>ConstraintViolation</em>,其中消息“ <em>Name不能为null</em> ”。</span></span></span></p> <h2 style="margin-left:0px; margin-right:0px; text-align:start"><strong>六,总结</strong></h2> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">本教程重点介绍了通过标准Java验证API的简单传递,并说明了使用<em>javax.validation</em>注释和API 进行bean验证的基础知识。</span></span></span></p> <p style="margin-left:0px; margin-right:0px; text-align:start"><span style="color:#535353"><span style="font-family:raleway"><span style="background-color:#ffffff">本文中的概念的实现可以在GitHub项目中找到。我们将在即将发布的文章中介绍JSR 380和Hibernate Validator的更多功能。</span></span></span></p> <br /> <br /> <br />  
  • Value '4320' is not valid duration

    Value '4320' is not valid duration.Checks Spring boot application .properties configuration files. Highlights  unresolved and deprecated configuration keys and invalid values .Works only for Spring Boot 1.2 or higher。Value '4200' is not
  • eclipse如何关闭java代码中某些部分/片段代码不被格式化

    eclipse如何关闭java代码中某些部分/片段代码不被格式化,eclipse,代码部分不被格式化,How to turn off the Eclipse code formatter for certain sections of Java code?eclipse如何关闭java代码中某些部分/片段代码不被格式化,eclipse,代码部分不被格式化,<br /> How to turn off the Eclipse code formatter for certain sections of Java code?<br /> <br /> 1.设置eclipse开启Off/On tags<br /> <br /> 依次点击菜单<br /> preferences->Java->Code Style->Formatter<br /> 点击Edit<br /> <img alt="1" class="img-thumbnail" src="/resources/assist/images/blog/d2fc6ee509064f309342ae36d146bb42.png" /><br /> <br /> 找到tag,点击enable Off/On tags<br /> <img alt="2" class="img-thumbnail" src="/resources/assist/images/blog/44a828ea10834828a6587602e9e42c03.png" /><br /> <br /> <br /> 在不想被格式化的代码之间添加以下注释标签即可<br />   <pre> <code class="language-java">import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.InputStream; import org.springframework.util.Base64Utils; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import com.alibaba.fastjson.JSONObject; import com.cqax.axschoolweb2.common.pojo.Result; /** * 验证码公用处理类 * * @author xq * */ @RestController public class ValidationCodeController { //@formatter:off /** * * @api {get} /apis/validation/getcode.json 获取验证码 * * @apiName GetValidateCode * * @apiGroup Validation * * @apiParam {String} [timeStamp] 时间戳 * * @apiSuccessExample {String} 返回值: * { "id": "1be34f4a324c4123b0325ecf0593d70e", "data": { "image": "iVBORwCCAAAAAAAAAAAAAAAAA==" }, "code": "00000", "dateTime": "2017-05-23 14:00:23", "msg": null } * */ //@formatter:on @GetMapping("/apis/validation/getcode.json") public Result getCode() { try { InputStream is = new FileInputStream(new File("e:/2.png")); ByteArrayOutputStream bao = new ByteArrayOutputStream(); byte[] cache = new byte[4096]; while (is.read(cache) != -1) { bao.write(cache); } String rs = Base64Utils.encodeToString(bao.toByteArray()); JSONObject obj = new JSONObject(); obj.put("image", rs); is.close(); return Result.success(obj); } catch (Exception e) { return Result.fail("eeeee", "错误,异常," + e.getMessage()); } } //@formatter:off /** * @api {get} /apis/validation/compare.json 对比验证码 * * @apiName CompareValidateCode * * @apiGroup Validation * * @apiParam {String} vcode 验证码 * * @apiSuccessExample {json} 返回值: * { "id":"f47611a1a7ee4d4c8c0420a4f7e4b228", "data":{ "result":true }, "code":"00000", "dateTime":"2017-05-23 14:41:36", "msg":null } */ //@formatter:on @GetMapping("/apis/validation/compare.json") public Result compare(String vcode) { JSONObject obj = new JSONObject(); obj.put("result", true);// 对比结果 return Result.success(obj); } public Result getPhoneCode(){ JSONObject obj=new JSONObject(); return null; } } </code></pre> <br />