简体   繁体   English

春季启动-结合DTO和表单验证

[英]Spring boot - Combine DTO and form validation

I am currently developing an API where I'm using DTO for the first time. 我目前正在开发一个API,这是我第一次使用DTO。 So far I've used Spring's form validation with javax.validation . 到目前为止,我已经将Spring的表单验证与javax.validation

So my question is if there is a way to combine both DTO and "form" validation. 所以我的问题是,是否有一种将DTO和“表单”验证结合起来的方法。 Let me explain myself: lets say I have a service to log in and another to register. 让我自己解释一下:假设我有一项服务可以登录,另外一项可以注册。 In the service to register we have: name, password and email, the 3 of them must be filled. 在注册服务中,我们有:名称,密码和电子邮件,必须填写其中三个。 As for the login service, only the email and password must be filled. 对于登录服务,只需填写电子邮件和密码。 So we'd have something like: 所以我们会有类似的东西:

private String name;
private String password;
private String email;

Until now, what I did was to create a POJO per request (forms) and then use annotations such as @NotNull but now with DTO in the project I'm in now they just have the same DTO and business object with the same properties and no constraints. 到目前为止,我所做的是为每个请求(表单)创建一个POJO,然后使用诸如@NotNull注释,但是现在在项目中使用DTO,现在它们只是具有相同的DTO和具有相同属性的业务对象,并且没有限制。

How could I do what I was usually doing? 我该怎么做我平时的工作? Checking the fields that must be not null in the controller looks a little dirty to me and I can't just put something like @NotNull in the UserDTO because then in the two examples I said I'd have to send also the name when logging in although it's not needed for that service. 在控制器中检查必须为非null的字段对我来说有点脏,我不能只在UserDTO放置类似@NotNull之类的UserDTO因为然后在两个示例中,我说我必须在登录时也发送name尽管该服务不是必需的。

So, how could I combine these 2 things? 那么,我如何将这两件事结合起来呢? Is this something not possible or there's a better approach? 这是不可能的还是有更好的方法?

Thanks. 谢谢。

I assume you are using two separate controllers for login and register requests. 我假设您使用两个单独的控制器进行登录和注册请求。 And if it is the case, then you can make good use of org.springframework.validation.Validator interface: 如果是这种情况,那么您可以充分利用org.springframework.validation.Validator接口:

@Component("registrationValidator")
public class RegistrationValidatorImpl implements Validator {

    @Override
    public boolean supports(final Class<?> aClass) {
    }

    @Override
    public void validate(final Object o, final Errors errors) {
    }
}

Create RegistrationValidatorImpl and LoginValidatorIml and @Autowire it in your controllers. 在您的控制器中创建RegistrationValidatorImpl和LoginValidatorIml并使用@Autowire对其进行创建。

The usage of validator is simple: 验证器的用法很简单:

invokeValidator(registrationValidator, someDTO, errors);

if (errors.hasErrors()) {
    return new ResponseEntity(HttpStatus.BAD_REQUEST); //or whatever logic here
}

The controller method signature should be similar to this: 控制器方法签名应与此类似:

@RequestMapping(value = "/register", method = RequestMethod.POST)
public ResponseEntity register(@RequestBody final SomeDTO someDTO, final HttpServletRequest request, final Errors errors) {}

I case of one controller, I assume you have different methods mapped to login and register requests. 以一个控制器为例,我假设您具有映射到登录和注册请求的不同方法。 You can @Autowire both validators in controller and use each in separate methods. 您可以@Autowire控制器中的两个验证器,并在单独的方法中使用它们。

Using groups for validation with javax.validation did the work. 使用组使用javax.validation进行验证可以javax.validation工作。 I followed the answer in this question (as Andrew suggested), then I just had to put every field I wanted to have different rules in different groups. 我遵循了这个问题的答案(就像安德鲁建议的那样),然后我只需要把我想要的每个字段都放在不同的组中。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM