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 支持我解决这个问题。
我遇到了 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 支持我解决这个问题。