无法使用@Valid在Spring Boot中验证请求正文

pan*_*ish 3 java spring jackson bean-validation spring-boot

我想用@Valid批注验证我的请求正文,但在Spring Boot中不起作用

我在JAR文件中有一个Request类,无法使用两个字段进行修改。一个字段是对象类型。我的控制器类接受该类对象作为请求主体。当我将下面的JSON传递给控制器​​时,验证不起作用。下面是代码示例。

要求类别:

public class Request {

    Object data;
    Map<String, Object> meta;

    public <T> T getData() throws ClassCastException {
        return (T) this.data;
    }
}
Run Code Online (Sandbox Code Playgroud)

另一类:

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
}
Run Code Online (Sandbox Code Playgroud)

控制器类别:

@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);
}
Run Code Online (Sandbox Code Playgroud)

调用代码设置请求如下:

StudentSignUpRequest studentSignUpRequest = new StudentSignUpRequest();
//setter methods

Request payload = new Request();
payload.setData(studentSignUpRequest);
Run Code Online (Sandbox Code Playgroud)

这是我发送的请求:

超过64个字符的firstName:

样本JSON:

{
    "data": {
        "firstName": "student111111111111111111111111111111111111111111111111111111111111",
        "lastName": "somesurname",
        "email": "developer@gmail.com"
    }
}
Run Code Online (Sandbox Code Playgroud)

不包括名字的地方:

{
    "data": {
        "lastName": "somesurname",
        "email": "developer@gmail.com"
    }
}
Run Code Online (Sandbox Code Playgroud)

在这里@Size,以及@NotNull注释均不起作用。

有什么办法吗?

bur*_*ete 5

如果Request上课的话,验证就可以了。

public class Request {

    @Valid
    StudentSignUpRequest data;

    // other stuff
}
Run Code Online (Sandbox Code Playgroud)

没有类类型的事实data使得无法在其上应用验证,而忽略@Valid了字段上甚至没有注释的事实。该@Valid注释用于传播验证级联。

但是由于您无法修改Request对象,因此让我们继续另一种无需手动进行验证的方法。


另一种方法是在获取StudentSignUpRequestfrom request对象之后触发验证。

StudentSignUpRequest signUpRequest = request.getData(StudentSignUpRequest.class);
loginRegistrationService.signUpStudent(signUpRequest) // validation will trigger with this call
Run Code Online (Sandbox Code Playgroud)

您可以做的如下:

@Service
@Validated
public class LoginRegistrationService {

    public void signUpStudent(@Valid StudentSignUpRequest signUpRequest) {
        // some logic
    }
}
Run Code Online (Sandbox Code Playgroud)

使用@Validated注解,您将激活该类@Valid中public方法中任何带注解的参数的验证检查。

可以与方法级别验证一起使用,指示应该在方法级别上验证特定的类(充当相应验证拦截器的切入点)

这可能会很昂贵,因为您希望尽快得到任何违反约束的信息,而不必为已经注定的请求做任何昂贵的工作。