2016-03-04 49 views
2

我正在與mybatis一起執行所有數據庫操作。我也在使用Angular前端,因此客戶端的驗證是使用angular-validation-ghiscoding和原生HTML5驗證進行的。我想驗證銀行端的數據,但我不想使用註釋。Java對象驗證在春季沒有註釋

下面是代碼的示例:

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

在同一I類必須創建一個帳戶的方法和我reciebe另一個模型對象(AccountRequestCreate accountRequest)。

哪個可能是最推薦的選項來實現而不使用xml既不註釋?

+0

諷刺的是,最推薦的方法是使用'@ Valid'或'@ validated'註解!註釋有什麼問題?您已經添加了一個'@ RequestBody',我想您可以騰出空間再添加一個註釋。 –

回答

3

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

如果傳遞豆違反了至少一個驗證規則,一個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); 
    } 
}