[英]Not able to validate request body in Spring boot with @Valid
I want to validate my request body with @Valid
annotation, but it's not working in Spring Boot我想使用@Valid
注释验证我的请求正文,但它在 Spring Boot 中不起作用
I have a Request class within JAR file which I can't modify with two fields.我在 JAR 文件中有一个请求 class,我无法用两个字段对其进行修改。 One field is of type Object. My controller class accept this class object as a request body.一个字段的类型是 Object。我的 controller class 接受这个 class object 作为请求主体。 When I pass my below JSON to the controller, validation is not working.当我将下面的 JSON 传递给 controller 时,验证不起作用。 Below are code samples.以下是代码示例。
Request Class:请求 Class:
public class Request {
Object data;
Map<String, Object> meta;
public <T> T getData() throws ClassCastException {
return (T) this.data;
}
}
Another Class:另一个Class:
public class StudentSignUpRequest {
@NotNull(message = "First Name should not be empty")
@Size(max = 64, message = "FirstName should not exceed 64 characters")
private String firstName;
@NotNull(message = "Last Name should not be empty")
@Size(max = 64, message = "LastName should not exceed 64 characters")
private String lastName;
@NotNull(message = "Email cannot be empty")
@Size(max = 50, message = "Email cannot exceed 50 characters")
@Pattern(regexp = EMAIL_REGEX_PATTERN, message = "Email should contain a valid email address.")
private String email;
// other fields
}
Controller Class: Controller Class:
@PostMapping(value = Constants.STUDENT_SIGN_UP)
public Response signUpStudent(@Valid @RequestBody Request request, HttpServletRequest servletRequest) {
// retrieving the actual resource from request payload
StudentSignUpRequest signUpRequest = request.getData(StudentSignUpRequest.class);
// call service to sign-up student
return loginRegistrationService.signUpStudent(signUpRequest);
}
Calling code sets request as below:调用代码设置请求如下:
StudentSignUpRequest studentSignUpRequest = new StudentSignUpRequest();
//setter methods
Request payload = new Request();
payload.setData(studentSignUpRequest);
This is the request I am sending:这是我发送的请求:
For more than 64 chars for firstName:对于 firstName 超过 64 个字符:
Sample JSON:样本 JSON:
{
"data": {
"firstName": "student111111111111111111111111111111111111111111111111111111111111",
"lastName": "somesurname",
"email": "developer@gmail.com"
}
}
Where first name not included:不包括名字的地方:
{
"data": {
"lastName": "somesurname",
"email": "developer@gmail.com"
}
}
Here both @Size
as well as @NotNull
annotation not working.这里@Size
和@NotNull
注释都不起作用。
Any solution?任何解决方案?
Validation would've worked if the Request
class was like;如果Request
类是这样的,验证就会起作用;
public class Request {
@Valid
StudentSignUpRequest data;
// other stuff
}
The fact that you have no class type for data
makes it impossible for validation to be applied on it, ignoring the fact that there isn't even a @Valid
annotation on the field.您没有data
类类型这一事实使得无法对其应用验证,忽略字段上甚至没有@Valid
注释的事实。 The @Valid
annotation is used to propagate the validation cascade. @Valid
注释用于传播验证级联。
But since you cannot modify Request
object, let's continue with another way to handle validation without doing it manually.但是由于您无法修改Request
对象,让我们继续使用另一种方法来处理验证,而无需手动进行。
Another way is to trigger validation after you get the StudentSignUpRequest
from request
object;另一种方法是在从request
对象中获取StudentSignUpRequest
后触发验证;
StudentSignUpRequest signUpRequest = request.getData(StudentSignUpRequest.class);
loginRegistrationService.signUpStudent(signUpRequest) // validation will trigger with this call
What you can do is as follows;你可以做的如下;
@Service
@Validated
public class LoginRegistrationService {
public void signUpStudent(@Valid StudentSignUpRequest signUpRequest) {
// some logic
}
}
with @Validated
annotation, you will activate the validation check for any @Valid
annotated args in public
methods within that class.使用@Validated
批注,您将激活对该类中public
方法中的任何@Valid
批注参数的验证检查。
Can be used with method level validation, indicating that a specific class is supposed to be validated at the method level (acting as a pointcut for the corresponding validation interceptor)可与方法级别验证一起使用,表示应该在方法级别验证特定类(充当相应验证拦截器的切入点)
This can be costly since you'd want to get any constraint violation as soon as possible without doing any costly jobs for an already doomed request.这可能是昂贵的,因为您希望尽快获得任何违反约束的情况,而无需为已经注定的请求做任何昂贵的工作。
没有验证将按照您使用它的方式工作,您需要将 @valid 放在请求对象内的对象上,但由于您无法控制该类,因此另一种方法是扩展 Request 对象并覆盖 getData 方法并应用 @valid在这种方法上,它应该以这种方式工作。
So you can use below code for validating the same.因此,您可以使用以下代码进行验证。
public <T> T getData() throws ClassCastException, SomeCustomValidationException {
ValidatorFactory factory = Validation.buildDefaultValidatorFactory();
validator = factory.getValidator();
Set s = validator.validate(this.data);
//throw SomeCustomValidationException if set is not empty else return this.data
}
First use @NotEmpty
, @Notblank
for Strings.首先对字符串使用@NotEmpty
、 @Notblank
。 Then ensure you import javax.validation.constraints
not that of hibernate.然后确保您导入javax.validation.constraints
而不是 hibernate 的。 If you are using a custom validator, you will need (final BindingResult bindingResult)
as part of your controller method variable.如果您使用自定义验证器,则需要(final BindingResult bindingResult)
作为控制器方法变量的一部分。
A couple of things here: The type Object
for data
in Request
class makes it impossible for the validator to know that it is of type StudentSignUpRequest
.这里有几件事: Request
类中data
Object
类型使验证器不可能知道它是StudentSignUpRequest
类型。 So change the data type.所以改变数据类型。
public class Request {
StudentSignUpRequest data;
Map<String, Object> meta;
}
Secondly, though you have added @Valid
in the controller method, in order to validate fields in StudentSignUpRequest
you have to add @Valid here as well.其次,虽然你已经添加@Valid
在控制器的方法,以在验证领域StudentSignUpRequest
你必须添加@Valid这里。 Now, data will be validated if passed in the API request.现在,如果在 API 请求中传递数据,将对其进行验证。 In case it is absent validation won't take place.如果不存在,则不会进行验证。 If you want to make data to be mandatorily passed add @NotNull as well.如果你想让数据被强制传递,也添加@NotNull。
public class Request {
@Valid
@NotNull
StudentSignUpRequest data;
Map<String, Object> meta;
}
did you add following dependency?您是否添加了以下依赖项?
spring-boot-starter-validation
also check https://www.baeldung.com/spring-boot-bean-validation还要检查https://www.baeldung.com/spring-boot-bean-validation
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.