Spring boot @Valid 不能正常工作

Spring boot @Valid does not work properly

我遇到了 Spring 启动验证问题。目前,我正在使用 Oracle JDK 11.0.12 和 Spring boot 2.5.4 来构建我的项目。我添加了约束来验证字段,但它不起作用。我的代码在这里:

import lombok.Data;

import javax.validation.constraints.NotBlank;
import javax.validation.constraints.NotNull;
import java.io.Serializable;

@Data
public class LoginFormDTO implements Serializable {

    private static final long serialVersionUID = 1L;

    @NotBlank(message = "Login must not be blank")
    private String login;

    @NotNull(message = "Password must be provided")
    private String password;

    private boolean rememberMe = false;
}
@RestController
@RequestMapping("/api")
public class AccountResource {

    // Logger and autowired components

    @PostMapping("/authenticate")
    @ResponseBody
    public ResponseEntity<JWTToken> authorize(@Valid @RequestBody LoginFormDTO account) {
        // Some code lines
        return ResponseEntity.ok().body(new JWTToken(jwt));
    }
}

pom.xml

中的依赖项
<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jdbc</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-jpa</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-rest</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jdbc</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-mail</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-security</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-thymeleaf</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-validation</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-web-services</artifactId>
    </dependency>
    <dependency>
        <groupId>org.liquibase</groupId>
        <artifactId>liquibase-core</artifactId>
    </dependency>
    <dependency>
        <groupId>org.thymeleaf.extras</groupId>
        <artifactId>thymeleaf-extras-springsecurity5</artifactId>
    </dependency>

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-devtools</artifactId>
        <scope>runtime</scope>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <scope>runtime</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-configuration-processor</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.projectlombok</groupId>
        <artifactId>lombok</artifactId>
        <optional>true</optional>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>org.springframework.security</groupId>
        <artifactId>spring-security-test</artifactId>
        <scope>test</scope>
    </dependency>
    <dependency>
        <groupId>com.googlecode.libphonenumber</groupId>
        <artifactId>libphonenumber</artifactId>
        <version>8.12.31</version>
    </dependency>
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-boot-starter</artifactId>
        <version>3.0.0</version>
    </dependency>
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-swagger-ui</artifactId>
        <version>3.0.0</version>
    </dependency>
    <dependency>
        <groupId>io.springfox</groupId>
        <artifactId>springfox-bean-validators</artifactId>
        <version>3.0.0</version>
    </dependency>
    <dependency>
        <groupId>io.jsonwebtoken</groupId>
        <artifactId>jjwt</artifactId>
        <version>0.9.1</version>
    </dependency>
</dependencies>

我希望当我发送 POST 带有正文的请求时

{
  "login": null, // or empty string "", or blank string "    "
  "password": "string",
  "rememberMe": true
}

然后服务器应该在我的 authorize(@Valid @RequestBody LoginFormDTO account) 函数中执行代码之前验证字段然后抛出异常或错误(因为违反空约束),但它没有。那么 spring 验证有什么问题还是我遗漏了什么?

您可以简化您的 Controller。你有太多的注解做同样的事情甚至一些奇怪的东西(你 return ResponseEntity 但是你告诉 Spring 方法的 return 应该是 Response正文)。

这可能无法解决 @Valid 问题,但肯定会使它变得更简单:

@RestController
@RequestMapping("/api")
public class AccountResource {

    // Logger and autowired components

    @PostMapping("/authenticate")
    @ResponseStatus(HttpStatus.OK)
    public JWTToken authorize(@Valid @RequestBody LoginFormDTO account) {
        // Some code lines
        return new JWTToken(jwt);
    }
}

@RestController 本身用 @Controller@ResponseBody 注释,这意味着 @RequestMapping 方法默认采用 @ResponseBody 语义,因此您不需要需要明确添加。

我发现我的 SwaggerConfig class 应该使用 BeanValidatorPluginsConfiguration.class 而不是 @Import({}) 中的 SpringValidatorAdapter.class。现在我的验证器工作正常。感谢 João Dias 支持我解决这个问题。