javax.validation 2.0.1 List<Object> 在 spring 引导中不工作
javax.validation 2.0.1 List<Object> not working in spring boot
我是 spring 引导开发的新手。我正在尝试通过从@RequestBody 传递列表来验证 post 请求。下面是控件class
@CrossOrigin
@RestController
@RequestMapping("/webapi/device")
@Validated
public class DeviceController extends AuthControllerImpl{
@Autowired
private DeviceServices deviceServices;
//Test Postman request 01
@PostMapping(path = "/udateDevices", consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON)
public ResponseEntity<Object> updateDeviceToDB( @RequestBody List<@Valid Device> device, @RequestParam("token") String token, Errors errors) {
if (errors.hasErrors()) {
return new ResponseEntity<Object>(new ErrorResponse(errors), HttpStatus.BAD_REQUEST);
}
if(isValidToken(token) != null){
DeviceControllerResponse response = deviceServices.updateDeviceToDB(device);
if (!response.isSuccess()) {
return new ResponseEntity<Object>(response, HttpStatus.BAD_REQUEST);
}
return ResponseEntity.ok(response);
}else {
return new ResponseEntity<Object>("Token has been expired/not valid.", HttpStatus.UNAUTHORIZED);
}
}
}
下面是我的实体class。
import javax.validation.constraints.NotEmpty;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document(collection = "rpDevices")
public class Device {
@Id
private String id;
@NotEmpty(message = "device udid should not be empty")
private String udid;
@NotEmpty(message = "deviceModel should not be empty")
private String deviceModel;
@NotEmpty(message = "device location should not be empty")
private String location;
@NotEmpty(message = "device port should not be empty")
private String port;
private String url;
private String lastUpdate;
private String imsi;
private String msisdn;
private String aliasName;
public Device() {
super();
}
public Device(String id, String udid, String deviceModel, String location, String port, String url,
String lastUpdate, String imsi, String msisdn, String aliasName) {
this.id = id;
this.udid = udid;
this.deviceModel = deviceModel;
this.location = location;
this.port = port;
this.url = url;
this.lastUpdate = lastUpdate;
this.imsi = imsi;
this.msisdn = msisdn;
this.aliasName = aliasName;
}
//Getter and setters
}
它从不验证实体并给出以下错误。
{
"timestamp": 1591497348682,
"status": 500,
"error": "Internal Server Error",
"exception": "javax.validation.UnexpectedTypeException",
"message": "HV000030: No validator could be found for constraint 'javax.validation.constraints.NotEmpty' validating type 'java.lang.String'. Check configuration for 'updateDeviceToDB.device[0].port'",
"path": "/xxxx/webapi/device/udateDevices"
}
有人可以帮助如何直接从请求日期验证列表。
https://www.baeldung.com/spring-validate-list-controller 我试过了,但没有帮助。
这里是 pom 依赖项
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.21.RELEASE</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Adding spring boot cap -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-mockmvc</artifactId>
<scope>test</scope>
</dependency>
<!-- Adding spring boot security,ldap -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-ldap</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<!-- starter-data-mongodb MongoRepository -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<!-- javax.mail -->
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.5.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.validation/validation-api -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<!-- some other stuff related to testing -- >
</dependencies>
Errors
参数应跟在经过验证的参数之后:
public ResponseEntity<Object> updateDeviceToDB( @RequestBody List<@Valid Device> device, Errors errors, @RequestParam("token") String token)
为了在单个方法中支持多个经过验证的参数,这是必需的。
public ResponseEntity<Object> updateDeviceToDB(@Valid @RequestBody List<Device> device, @RequestParam("token") String token, Errors errors)
在绑定用户输入后验证模型是很常见的。 Spring 3 提供对 JSR-303 声明式验证的支持。如果您的类路径中存在 JSR-303 提供程序(例如 Hibernate Validator),则会自动启用此支持。启用后,您可以简单地通过使用 @Valid 注释对 Controller 方法参数进行注释来触发验证:
访问这个 Link : https://spring.io/blog/2009/11/17/spring-3-type-conversion-and-validation/
validation-api是规范,hibernate-validator是实现,简单来说
spring-boot-starter-web会自动导入hibernate-validator,然后hibernate -validator 会自动导入 validation-api.
加上你的jar依赖配置,有两个版本validation-api
。一个是由 hibernate-validator 5.3.6
(来自 spring-boot-starter-web)导入的 1.1.0
,另一个是由您的显式声明导入的 2.0.1
。 validation-api 2.0.1
将与 hibernate-validator 5.3.6
一起使用,这是不兼容的。导致找不到验证器错误。
当您删除 validation-api 2.0.1
时,将使用 1.1.0
版本。但是 javax.validation.constraints.NotEmpty
没有和 validation-api 1.1.0
一起引入,所以你会得到另一个错误。
解决这个问题的几种方法:
- 删除
validation-api 2.0.1
,使用 org.hibernate.validator.constraints.NotEmpty
代替 javax.validation.constraints.NotEmpty
。
- 删除
validation-api 2.0.1
,升级spring引导版本到2.x,它将使用hibernate-validator6.x和validation-api2.x.
- 保留您明确的
validation-api 2.0.1
声明。然后添加另一个 hibernate-validator 6.0.14
声明。此案例应该经过全面测试,因为可能存在一些 Spring 支持问题。
我遇到了类似的问题,如果您使用的是 spring 引导版本 (2.3.0) 及更高版本,那么 validation-api
将无法工作。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
只需要在pom.xml
中添加上面的依赖即可。
请参阅发行说明:https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.3-Release-Notes#validation-starter-no-longer-included-in-web-starters
我是 spring 引导开发的新手。我正在尝试通过从@RequestBody 传递列表来验证 post 请求。下面是控件class
@CrossOrigin
@RestController
@RequestMapping("/webapi/device")
@Validated
public class DeviceController extends AuthControllerImpl{
@Autowired
private DeviceServices deviceServices;
//Test Postman request 01
@PostMapping(path = "/udateDevices", consumes = MediaType.APPLICATION_JSON, produces = MediaType.APPLICATION_JSON)
public ResponseEntity<Object> updateDeviceToDB( @RequestBody List<@Valid Device> device, @RequestParam("token") String token, Errors errors) {
if (errors.hasErrors()) {
return new ResponseEntity<Object>(new ErrorResponse(errors), HttpStatus.BAD_REQUEST);
}
if(isValidToken(token) != null){
DeviceControllerResponse response = deviceServices.updateDeviceToDB(device);
if (!response.isSuccess()) {
return new ResponseEntity<Object>(response, HttpStatus.BAD_REQUEST);
}
return ResponseEntity.ok(response);
}else {
return new ResponseEntity<Object>("Token has been expired/not valid.", HttpStatus.UNAUTHORIZED);
}
}
}
下面是我的实体class。
import javax.validation.constraints.NotEmpty;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;
@Document(collection = "rpDevices")
public class Device {
@Id
private String id;
@NotEmpty(message = "device udid should not be empty")
private String udid;
@NotEmpty(message = "deviceModel should not be empty")
private String deviceModel;
@NotEmpty(message = "device location should not be empty")
private String location;
@NotEmpty(message = "device port should not be empty")
private String port;
private String url;
private String lastUpdate;
private String imsi;
private String msisdn;
private String aliasName;
public Device() {
super();
}
public Device(String id, String udid, String deviceModel, String location, String port, String url,
String lastUpdate, String imsi, String msisdn, String aliasName) {
this.id = id;
this.udid = udid;
this.deviceModel = deviceModel;
this.location = location;
this.port = port;
this.url = url;
this.lastUpdate = lastUpdate;
this.imsi = imsi;
this.msisdn = msisdn;
this.aliasName = aliasName;
}
//Getter and setters
}
它从不验证实体并给出以下错误。
{
"timestamp": 1591497348682,
"status": 500,
"error": "Internal Server Error",
"exception": "javax.validation.UnexpectedTypeException",
"message": "HV000030: No validator could be found for constraint 'javax.validation.constraints.NotEmpty' validating type 'java.lang.String'. Check configuration for 'updateDeviceToDB.device[0].port'",
"path": "/xxxx/webapi/device/udateDevices"
}
有人可以帮助如何直接从请求日期验证列表。 https://www.baeldung.com/spring-validate-list-controller 我试过了,但没有帮助。
这里是 pom 依赖项
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.21.RELEASE</version>
<scope>import</scope>
<type>pom</type>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<!-- Adding spring boot cap -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-thymeleaf</artifactId>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.springframework.restdocs</groupId>
<artifactId>spring-restdocs-mockmvc</artifactId>
<scope>test</scope>
</dependency>
<!-- Adding spring boot security,ldap -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.ldap</groupId>
<artifactId>spring-ldap-core</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-ldap</artifactId>
</dependency>
<!-- https://mvnrepository.com/artifact/io.jsonwebtoken/jjwt -->
<dependency>
<groupId>io.jsonwebtoken</groupId>
<artifactId>jjwt</artifactId>
<version>0.9.1</version>
</dependency>
<!-- starter-data-mongodb MongoRepository -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-mongodb</artifactId>
</dependency>
<!-- javax.mail -->
<dependency>
<groupId>com.sun.mail</groupId>
<artifactId>javax.mail</artifactId>
<version>1.5.5</version>
</dependency>
<!-- https://mvnrepository.com/artifact/javax.validation/validation-api -->
<dependency>
<groupId>javax.validation</groupId>
<artifactId>validation-api</artifactId>
<version>2.0.1.Final</version>
</dependency>
<!-- some other stuff related to testing -- >
</dependencies>
Errors
参数应跟在经过验证的参数之后:
public ResponseEntity<Object> updateDeviceToDB( @RequestBody List<@Valid Device> device, Errors errors, @RequestParam("token") String token)
为了在单个方法中支持多个经过验证的参数,这是必需的。
public ResponseEntity<Object> updateDeviceToDB(@Valid @RequestBody List<Device> device, @RequestParam("token") String token, Errors errors)
在绑定用户输入后验证模型是很常见的。 Spring 3 提供对 JSR-303 声明式验证的支持。如果您的类路径中存在 JSR-303 提供程序(例如 Hibernate Validator),则会自动启用此支持。启用后,您可以简单地通过使用 @Valid 注释对 Controller 方法参数进行注释来触发验证:
访问这个 Link : https://spring.io/blog/2009/11/17/spring-3-type-conversion-and-validation/
validation-api是规范,hibernate-validator是实现,简单来说
spring-boot-starter-web会自动导入hibernate-validator,然后hibernate -validator 会自动导入 validation-api.
加上你的jar依赖配置,有两个版本validation-api
。一个是由 hibernate-validator 5.3.6
(来自 spring-boot-starter-web)导入的 1.1.0
,另一个是由您的显式声明导入的 2.0.1
。 validation-api 2.0.1
将与 hibernate-validator 5.3.6
一起使用,这是不兼容的。导致找不到验证器错误。
当您删除 validation-api 2.0.1
时,将使用 1.1.0
版本。但是 javax.validation.constraints.NotEmpty
没有和 validation-api 1.1.0
一起引入,所以你会得到另一个错误。
解决这个问题的几种方法:
- 删除
validation-api 2.0.1
,使用org.hibernate.validator.constraints.NotEmpty
代替javax.validation.constraints.NotEmpty
。 - 删除
validation-api 2.0.1
,升级spring引导版本到2.x,它将使用hibernate-validator6.x和validation-api2.x. - 保留您明确的
validation-api 2.0.1
声明。然后添加另一个hibernate-validator 6.0.14
声明。此案例应该经过全面测试,因为可能存在一些 Spring 支持问题。
我遇到了类似的问题,如果您使用的是 spring 引导版本 (2.3.0) 及更高版本,那么 validation-api
将无法工作。
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-validation</artifactId>
</dependency>
只需要在pom.xml
中添加上面的依赖即可。
请参阅发行说明:https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.3-Release-Notes#validation-starter-no-longer-included-in-web-starters