繁体   English   中英

@valid 注释未按预期工作

[英]@valid annotation is not working as expected

我正在使用请求有效负载中的对象数组调用 API,我在 @RequestBody 上添加了@valid 注释,以检查是否在我的有效负载中发送了任何空属性。 我期待我发送的任何空数据是否会引发错误。 但我的代码没有抛出错误

下面是我的实体类

@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
@DynamicUpdate
@Entity
@Table(name = "student")
public class Student {

   @Id
   @Column(name = "student_id")
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   private Integer studentId;

   @NotNull
   @Column(name = "name")
   private String name;

   @NotNull
   @Column(name = "gender")
   private String gender;

}

这是我的控制器类

@RestController
@CrossOrigin
public class StudentController {

   @PostMapping("/class/{classId}/student")
   public Student addStudent(@PathVariable Integer classId,@Valid @RequestBody List<Student>  
           student) {

     // My logic Comes Here
     return Student;
    }
  }

验证依赖

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId>
    </dependency>

我的请求负载

[{
   "name":"kiran",
   "gender":"male"
 },
 {
    "name":"divya"
 } 
]

当我发送上述有效负载时,我预计需要抛出一个错误,因为我没有发送不为空的性别,但是 spring 没有抛出任何错误。

我想念@valid 工作的东西吗?

如果您使用 Spring Boot 2.3.3.RELEASE。 然后在 POM 中添加以下依赖项:

<dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

使用示例:

//update audTipo
@PutMapping("audTipo/{id}")
public ResponseEntity<AudTipo> update(@PathVariable(value="id") Integer audTipoId, 
        @Valid @RequestBody AudTipo audTipoDetils) throws ResourceNotFundException
{   
    
      AudTipo audTipo = audTipoRepository.findById(audTipoId).orElseThrow(()-> new
      ResourceNotFundException("NF " + audTipoId));
      audTipo.setXdesc(audTipoDetils.getXdesc());
      
      return ResponseEntity.ok(this.audTipoRepository.save(audTipo));    
}

如果您遇到例如:无法看到返回给客户端的验证错误(默认消息)的问题,您可以这样做:

最佳解决方案 1:只需添加 devtools。 这应该可以解决问题。 在我这样做之后,我所有的绑定结果都返回给了客户端。 我建议你先测试一下:

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-devtools</artifactId>
</dependency>

解决方案2:

我发现这是由于使用 Spring Boot 2.3+ 所以如果您使用的是 Spring Boot 2.3 或更高版本,请将此依赖项添加到您的 pom.xml 文件中,因为它不再包含在“web”依赖项本身中。

<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-validation</artifactId>
</dependency>

现在有必要将java/resources/application.properties中的“包含绑定错误”设置为“始终”。 “消息”也是如此,尽管我认为这是可选的。

server.error.include-message=always
server.error.include-binding-errors=always

解决方案 3 :(在我发现解决方案 2 之前也有帮助)

所以我发现这是由于 Spring boot 2.3+。 但是我找不到有关 Spring Boot v2.3+​​ 中 @Valid 的新更新用法的警告消息。

所以我最终通过调整 pom.xml 文件中的发布版本切换回 Spring boot v2.2.10(2.2 的最新版本),如下所示:

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>2.2.10.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

通过回滚到旧版本,这对我来说非常有效。 虽然 id 喜欢在某一天更新我的 Spring Boot 版本。 (重温解决方案 1 和 2)

您不能将@Valid应用于java.util.List

请参阅: Spring MVC - REST 服务中 bean 列表上的 @Valid

您的@Valid注释应用于列表而不是列表中存在的实际对象。

您在示例中的注释验证列表而不是列表的每个对象。

试试这个

public Student addStudent(@PathVariable Integer classId,@RequestBody List<@Valid Student> students)

您还可以指定其他参数,例如您可能需要验证列表中的每个对象,并确保列表不为空,或具有最小大小等。必须对列表执行这些验证。

当 Spring Boot 找到一个用 @Valid 注释的参数时,它会自动引导默认的 JSR 380 实现——Hibernate Validator——并验证该参数。

仅当请求本身为 NULL 时才会违反 JSR 380 实现。 如上所述,它不能用于检查请求正文中的空值。

我知道您正在使用构建的 Maven,但我遇到了类似的问题,即标签无法集成到构建的 Gradle 中。

我通过获取正确版本的依赖项来解决它。

implementation 'org.springframework.boot:spring-boot-starter-validation:2.4.0'

代替

implementation 'org.springframework.boot:spring-boot-starter-validation'

如果有人知道这是否正确,但它现在有效。

如果您使用的是Kotlin ,则需要使用

  @field:Email() val email: String

代替

  @Email() val email: String

验证工作。

请参阅https://kotlinlang.org/docs/annotations.html#annotation-use-site-targetshttps://stackoverflow.com/a/36521309/570168

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM