簡體   English   中英

春季沒有注釋的Java對象驗證

[英]Java objects validation in spring without annotations

我正在與mybatis一起執行所有數據庫操作。 我也在使用Angular前端,因此客戶端中的驗證是使用angular-validation-ghiscoding和本機HTML5驗證進行的。 我想驗證銀行端的數據,但是我不想使用注釋。

這是代碼示例:

    @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;
    }

在同一個類中,我有一個創建帳戶的方法,我收到了另一個模型對象( AccountRequestCreate accountRequest )。

哪一個是不帶XML且不帶注釋的實現的最推薦選項?

最推薦的方法是使用@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
    }
}

使用這種方法,您將在所有其他控制器中重復驗證邏輯,這不是一個好主意。 而且您違反了DRY原則。

正如我所說的,最好用@Valid@Validated注釋您的bean:

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

如果傳遞的bean至少違反一個驗證規則, MethodArgumentNotValidException引發MethodArgumentNotValidException 為了處理該異常,您可以編寫一個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