【问题标题】:@Valid not working for spring rest controller@Valid 不适用于弹簧休息控制器
【发布时间】:2020-09-25 00:15:56
【问题描述】:

我已经定义了一个休息端点方法:

@GetMapping("/get")
public ResponseEntity getObject(@Valid MyObject myObject){....}

这会将请求参数映射到 MyObject。

MyObject 定义为(带有 lombok、javax.validation 注释):

@Value
@AllArgsConstructor
public class MyObject {

    @Min(-180) @Max(180)
    private double x;

    @Min(-90) @Max(90)
    private double y;

}

但验证不起作用。即使值超出规定范围,请求也不会抛出错误并且运行良好。

【问题讨论】:

  • 你找到答案了吗?我们有同样的问题。

标签: spring-boot rest lombok javax.validation


【解决方案1】:

我只需添加以下依赖项即可使验证正常工作。

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

【讨论】:

    【解决方案2】:

    如果您使用的是 Spring Boot > 2.3 版本,则它现在声明

    网络启动器中不再包含验证启动器

    ...您需要自己添加启动器。

    对于 Maven 构建,您可以执行以下操作:

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

    对于 Gradle,您需要添加如下内容:

    dependencies {
      ...
      implementation 'org.springframework.boot:spring-boot-starter-validation'
    }
    

    请参考https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.3-Release-Notes#validation-starter-no-longer-included-in-web-starters

    【讨论】:

      【解决方案3】:

      org.springframework.validation.annotation.Validated注释你的控制器

      【讨论】:

        【解决方案4】:

        我在这里看到了一些你应该解决的问题。让我们开始讨论 REST 标准,第一条规则是将端点视为资源的表示,而不是操作,例如,在您的代码中,我假设 MyObject 类代表一个点(您应该重构该类以具有正确名称),那么getObject 的路径值可以是“/point”。相应地,这些操作映射到 HTTP 方法上:

        • GET:获取有关资源的信息。
        • POST:创建资源。
        • PUT:更新资源。
        • DELETE:删除资源。

        getObject 中,您希望收到一个对象。根据 REST 标准的 get 方法意味着您要检索一些数据,通常您发送一些包含在 url 中的数据,例如 ../app-context/get/{id},这里 id 是一个参数,告诉您的控制器你想要一些属于一个 id 的信息,所以如果你像 ../app-context/get/1 这样调用端点来获取一些由数字 1 标识的域对象的信息。

        如果要向服务器发送数据,最常见的 HTTP 方法是 POST。

        据此,在设计层面你应该:

        • 为 MyObject 类取一个有意义的名称。
        • getObject中勾选你要进行的操作。
        • 为代表资源的getObject 分配路径。

        在代码级别,使用上述 cmets,您可以将其更改为:

        @Data
        @AllArgsConstructor
        @NoArgsConstructor
        public class MyObject {
        
          @Min(-180) @Max(180)
          private double x;
        
          @Min(-90) @Max(90)
          private double y;
        }
        

        @PostMapping("/point")
        public ResponseEntity savePoint(@RequestBody @Valid MyObject myObject) {...}
        

        我将解释这些变化:

        • 添加 @PostMapping 以符合 REST 标准。
        • 添加@RequestBody,这个注解把发送到服务器的信息用来创建一个MyObject对象。
        • 将@NoArgsConstructor 添加到MyObject,默认情况下,反序列化使用默认构造函数(不带参数)。您可以编写一些专门的代码来使事情在没有默认构造函数的情况下工作,但这取决于您。

        【讨论】:

          猜你喜欢
          • 2020-03-17
          • 2014-08-27
          • 1970-01-01
          • 2017-09-01
          • 2020-05-16
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多