Spring验证框架解决错误代码

时间:2015-10-31 21:31:28

标签: java spring validation spring-mvc

如何将Spring Validation Errors连接到messages.properties中的错误字符串?

  • 我的Validator抛出一个包装spring Errors对象的自定义RuntimeException。
  • 我的@ControllerAdvice拦截异常,并将RuntimeException转换为名为WebExceptionMessage的DTO对象。
  • DTO WebExceptionMessage对象有一个自定义WebValidationError对象列表,它们是Spring Errors对象的转换。
  • 我的classpath中有messages.properties,其中的键与Spring Validation Errors对象中的错误代码相匹配。

如何,何时何地使用messages.properties中的值来补充Spring验证错误?

我阅读了关于自动布线的所有内容并尝试了它们,但无论我做什么都不起作用......

enter image description here

的src /主/资源/ messages.properties

field.required=Missing mandatory field.
field.numeric_only=Field must contain numbers only.
// more

MyValidator.java

@Component
public class MyValidator implements Validator{
  // code
  public void validate(Object target, Errors errors) {
    ValidationUtils.rejectIfEmpty(errors, "audit", "field.required");
    if(errors.hasErrors()){
      throw new MyRuntimeException(MyErrorCode.INVALID_REQUEST, "Failed Validator").errors(errors);
    }   
  }
}

WebExceptionHandler.java

@ControllerAdvice
public class WebExceptionHandler {
  @ExceptionHandler(value=MyRuntimeException.class)
  public ResponseEntity<WebExceptionMessage> myRuntimeException(MyRuntimeException e){
    WebExceptionMessage msg = new WebExceptionMessage();

    // code

    if(e.hasErrors()){
      List<WebValidationError> errors = new ArrayList<WebValidationError>();
      List<FieldError> fieldErrors = e.getErrors().getFieldErrors();
      for(FieldError err : fieldErrors){

        // =============================
        // I think somewhere over here I need to map the err.getCode()
        // to the value in messages.properties but isn't spring supposed 
        // to "magically" do that somehow and place the value in err.getDefaultMessage()
        //
        // I am probably completely off base here...please advise.
        // =============================

        errors.add(new WebValidationError(err.getCode(), err.getField(), err.getDefaultMessage()));


      }
      msg.setErrors(errors);
    }

    return new ResponseEntity<WebExceptionMessage>(msg, e.getErrorCode().getStatus());
  }
}

MyRuntimeException.java

public class MyRuntimeException extends RuntimeException {
  private org.springframework.validation.Errors errors;
  // code
  public MyRuntimeException errors(final Errors errors){
    this.errors = errors;
    return this;
  }  
}

WebExceptionMessage.java

public class WebExceptionMessage implements Serializable{
  // code
  private List<WebValidationError> errors;
}

1 个答案:

答案 0 :(得分:3)

我明白了!我只是将MessageSource自动装入我的@ControllerAdvice并进行查找&#34;手动&#34;。这有效,但我认为春天(或春天开机?)假设自动执行此操作?

enter image description here

@ControllerAdvice
public class WebExceptionHandler {

  @Autowired
  MessageSource errorMessageSource;

  @ExceptionHandler(value=MyRuntimeException.class)
  public ResponseEntity<WebExceptionMessage> myRuntimeException(MyRuntimeException e){
    WebExceptionMessage msg = new WebExceptionMessage();

    // code

    if(e.hasErrors()){
      List<WebValidationError> errors = new ArrayList<WebValidationError>();
      List<FieldError> fieldErrors = e.getErrors().getFieldErrors();
      for(FieldError err : fieldErrors){

        // =============================
        // "Manually" extract the message.
        // =============================
        String message = errorMessageSource.getMessage(err.getCode(), err.getArguments(), null);
        errors.add(new WebValidationError(err.getCode(), err.getField(), message));


      }
      msg.setErrors(errors);
    }

    return new ResponseEntity<WebExceptionMessage>(msg, e.getErrorCode().getStatus());
  }
}