简体   繁体   English

春季没有注释的Java对象验证

[英]Java objects validation in spring without annotations

I'm working with mybatis to perform all database actions. 我正在与mybatis一起执行所有数据库操作。 I'm also working with an Angular front-end, so the validations in the client are made with angular-validation-ghiscoding and the native HTML5 validations. 我也在使用Angular前端,因此客户端中的验证是使用angular-validation-ghiscoding和本机HTML5验证进行的。 I would like to validate the data in the bank-end to, but I don't want to use annotations. 我想验证银行端的数据,但是我不想使用注释。

Here is an example of the code: 这是代码示例:

    @RequestMapping(value = SecureApiResources.URI_UPDATE_ACCOUNT, method = RequestMethod.POST, produces = "application/json")
    public @ResponseBody Account updateAccount(
            @RequestBody final AccountRequestUpdate accountRequest) { // Object to be validated (accountRequest)

        Account account = accountMapper.getAccountOfMerchant(authContextHolder.getMerchantId(), authContextHolder.getDefaultAccountId());

        if (account == null) {
            HttpErrors httpErrors = new HttpErrors(
                    SecureApiResources.ERROR_ACCOUNTS_NOT_FOUND);
            throw new EntityNotFoundException(httpErrors);
        }
        int resultUpdate;
        try {
            // In this point I should validate the accountRequest object
            account.setAccountName(accountRequest.getAccountName());
            account.setCommercialName(accountRequest.getCommerciaName());
            account.setCountry(accountRequest.getCountry());
            account.setCity(accountRequest.getCity());
            resultUpdate = accountMapper.updateMerchant(account);
            if (resultUpdate == 0) {
                HttpErrors httpErrors = new HttpErrors(
                        SecureApiResources.ERROR_ACCOUNTS_NOT_FOUND);
                throw new EntityNotFoundException(httpErrors);
            }
        } catch (Exception e) {
            HttpErrors httpErrors = new HttpErrors(
                    SecureApiResources.ERROR_SQL_NOT_EXECUTE);
            throw new EntityNotFoundException(httpErrors);
        }

        return account;
    }

In the same class I have a method to create an account and I reciebe another model object ( AccountRequestCreate accountRequest ). 在同一个类中,我有一个创建帐户的方法,我收到了另一个模型对象( AccountRequestCreate accountRequest )。

Which could be the most recommended option to implement without xml neither annotations? 哪一个是不带XML且不带注释的实现的最推荐选项?

The most recommended approach is using @Valid or @Validated annotations but since you're not totally OK with that, you can Autowire the javax.validation.Validator into your controller and perform the validation manually: 最推荐的方法是使用@Valid@Validated注解,但因为你无法与完全好了,可以Autowirejavax.validation.Validator到控制器中并手动进行验证:

@Controller
public class SomeController {
    @Autowired private Validator validator;

    @RequestMapping(...)
    public ResponseEntity<?> someHandler(@RequestBody SomeBody body) {
        Set<ConstraintViolation<SomeBody>> violations = validator.validate(body);
        if (!violations.isEmpty()) {
            List<String> messages = violations
                                   .stream()
                                   .map(ConstraintViolation::getMessage)
                                   .collect(Collectors.toList());

            return ResponseEntity.badRequest().body(messages);
        }
        // the rest of controller
    }
}

With this approach, you will repeat the validation logic in all other controllers which is, well, not a good idea. 使用这种方法,您将在所有其他控制器中重复验证逻辑,这不是一个好主意。 Also you're violating the DRY principle. 而且您违反了DRY原则。

As i said it's better to annotate your bean with @Valid or @Validated : 正如我所说的,最好用@Valid@Validated注释您的bean:

@RequestMapping(...)
public ResponseEntity<?> someHandler(@RequestBody @Valid SomeBody body) { ... }

If passed bean violates at least one validation rule, an MethodArgumentNotValidException would be thrown. 如果传递的bean至少违反一个验证规则, MethodArgumentNotValidException引发MethodArgumentNotValidException For handling that exception you can write a ControllerAdvice that catches the exception and return a suitable HTTP response, say a 400 Bad Request : 为了处理该异常,您可以编写一个ControllerAdvice来捕获该异常并返回合适的HTTP响应,例如400 Bad Request

@ControllerAdvice
public class ValidationAdvice {
    @ExceptionHandler(MethodArgumentNotValidException.class)
    public ResponseEntity<?> handleValidationError(MethodArgumentNotValidException ex) {
         List<String> validationErrors = ex.getBindingResult()
                                            .getAllErrors()
                                            .stream()
                                            .map(ObjectError::getDefaultMessage)
                                            .collect(Collectors.toList());

         return ResponseEntity.badRequest().body(validatioErrors);
    }
}

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

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