【问题标题】:Spring - Instantiating an Errors objectSpring - 实例化一个错误对象
【发布时间】:2012-10-03 17:41:39
【问题描述】:

我有这样的方法:

public boolean validateMessage(String message, Errors errors) {
  if (!StringUtils.hasLength(message)) {
    errors.rejectValue(wrapperName + "message", "EMPTY_MESSAGE", EMPTY_MESSAGE_ERRORMSG) ;
            return false ;
        }
        return true ;
    }

我想用一个新的Errors 对象来调用这个方法,比如:

boolean result = validateMessage("hi", new Errors()) ;

但是,Errors 不允许这种实例化。请指教。

如果不是Errors,我可以使用空的(新)BindingResult 来实现这一点

【问题讨论】:

标签: java spring


【解决方案1】:

ErrorsBindingResult 是接口,因此它们不能被实例化。您唯一的选择是使用实现Errors 的类之一。

你可以使用org.springframework.validation.BindException,这实现了Errors - see here for details

【讨论】:

  • 这不起作用,因为 BindException 不能转换为 Errors
  • 如果我尝试投射它,我会得到:java.lang.ClassCastException: java.net.BindException cannot be cast to org.springframework.validation.Errors。显然,这是不可能的。
  • org.springframework.validation.BindException 实现了Errors,所以应该是可以的。
  • BindException 可以在实现错误时进行强制转换。您正在实例化错误的 BindException 类 - 它不是 java.net.BindException 对象 - 它是 org.springframework.validation.BindException
  • java.net.BindException 是错误的类,您需要我上面评论中概述的类。
【解决方案2】:

另一个选择是使用 org.springframework.validation.BeanPropertyBindingResult,它实现了 Errors。此对象与您在 Spring MVC 控制器中收到的 BindingResult 属于同一类

Errors errors = new BeanPropertyBindingResult(objectToValidate, "objectName");

【讨论】:

    【解决方案3】:

    首先,您不能初始化 Errors 对象,因为这是一个接口。

    我正在尝试为我的 JUnit 测试用例初始化 Errors 对象。 Spring中的Errors有很多实现,(我在下面附上了一张图片)。

    我试过new EscapedErrors(null),但它的构造函数本身期望传递错误对象。

    解决方案org.springframework.validation.BeanPropertyBindingResult 的构造函数如下所示:

    public BeanPropertyBindingResult(Object target, String objectName) {
            this(target, objectName, true, Integer.MAX_VALUE);
        }
    

    所以对我来说,Errors errors = new BeanPropertyBindingResult(new Object(), "dummy"); 就像一个魅力。

    【讨论】:

      【解决方案4】:

      您可以实例化类对象。但Errors 是一个接口,而不是一个类。因此,它不能像您尝试的那样实例化。

      【讨论】:

      • 但是应该有办法解决这个问题。你是说我想做的事是不可能的吗? :(
      【解决方案5】:

      如果这是一个 Spring MVC 应用程序并且您正在使用 @Controllers,您可以以 org.springframework.validation.BindingResult 的形式传递您的验证对象作为映射的一部分:

      @RequestMapping(value="login.htm", method=RequestMethod.POST)
      public String doLogin(HttpServletRequest request, Model model, BindingResult errors) {
          // ..... some validation code
      
          String message = "My message";
          boolean valid = validateMessage(message, errors); 
      
          // .... some more code
      }
      

      这是显式实例化 org.springframework.validation.Errors 的另一种方法。

      【讨论】:

        【解决方案6】:

        大多数情况下,开发人员使用@ValidBindingResult 来验证发布的或新的对象。例如,在下面的代码中,通过@Valid 注释验证Category 对象,然后将其结果与BindingResult 绑定。但所有这些步骤都是由Spring 自动完成的。

        @PostMapping
        public String saveCategory(@Valid Category category, BindingResult bindingResult)
        {
            // if there are some errors
            if (bindingResult.hasErrors())
            {
                for (ObjectError objectError : bindingResult.getAllErrors())
                {
                    System.out.println(objectError.getDefaultMessage());
                }
            }
        
            ...
        }
        

        虽然上面提到的代码 sn-p 是 Spring 的突出优势之一,但偶尔你也希望在其他层有相同的行为。所以你必须得到一个 BindingResult 实现形式的实例,并在你的代码中注入一个验证器:

        ...
        import org.springframework.validation.Validator;
        ...
        
        @Service
        public class CategoryService
        {
        
            @Autowired
            private Validator validator;
            ...
        
            private void insertNewCategory(Category category)
            {
                BindingResult bindingResult = new BeanPropertyBindingResult(category, "objectName");
                validator.validate(category, bindingResult);
                if(bindingResult.hasErrors())
                {
                    for (FieldError fieldError : bindingResult.getFieldErrors())
                    {
                        System.out.println(fieldError.getDefaultMessage());
                    }
                }
            ....
            }
        }
        

        【讨论】:

          【解决方案7】:

          该方法需要一个实现Errors 接口的对象。任何实现 Errors 接口的类都可以工作。如果不想使用org.springframework.validation.BindException 等现有类,可以使用匿名内部类。有关已经实现 Errors 的现有类,请参阅 the Spring Docs。但是你的匿名类需要实现所有的接口方法,这些方法非常多,使你的代码越来越难以阅读:

          boolean result = validateMessage( "hi", new Errors() {
          
                  @Override
                  public void setNestedPath(String nestedPath) {
                      // TODO Auto-generated method stub
          
                  }
          
                  @Override
                  public void rejectValue(String field, String errorCode, Object[] errorArgs, String defaultMessage) {
                      // TODO Auto-generated method stub
          
                  }
          
                  @Override
                  public void rejectValue(String field, String errorCode, String defaultMessage) {
                      // TODO Auto-generated method stub
          
                  }
          
                  @Override
                  public void rejectValue(String field, String errorCode) {
                      // TODO Auto-generated method stub
          
                  }
          
                  @Override
                  public void reject(String errorCode, Object[] errorArgs, String defaultMessage) {
                      // TODO Auto-generated method stub
          
                  }
          
                  @Override
                  public void reject(String errorCode, String defaultMessage) {
                      // TODO Auto-generated method stub
          
                  }
          
                  @Override
                  public void reject(String errorCode) {
                      // TODO Auto-generated method stub
          
                  }
          
                  @Override
                  public void pushNestedPath(String subPath) {
                      // TODO Auto-generated method stub
          
                  }
          
                  @Override
                  public void popNestedPath() throws IllegalStateException {
                      // TODO Auto-generated method stub
          
                  }
          
                  @Override
                  public boolean hasGlobalErrors() {
                      // TODO Auto-generated method stub
                      return false;
                  }
          
                  @Override
                  public boolean hasFieldErrors(String field) {
                      // TODO Auto-generated method stub
                      return false;
                  }
          
                  @Override
                  public boolean hasFieldErrors() {
                      // TODO Auto-generated method stub
                      return false;
                  }
          
                  @Override
                  public boolean hasErrors() {
                      // TODO Auto-generated method stub
                      return false;
                  }
          
                  @Override
                  public String getObjectName() {
                      // TODO Auto-generated method stub
                      return null;
                  }
          
                  @Override
                  public String getNestedPath() {
                      // TODO Auto-generated method stub
                      return null;
                  }
          
                  @Override
                  public List<ObjectError> getGlobalErrors() {
                      // TODO Auto-generated method stub
                      return null;
                  }
          
                  @Override
                  public int getGlobalErrorCount() {
                      // TODO Auto-generated method stub
                      return 0;
                  }
          
                  @Override
                  public ObjectError getGlobalError() {
                      // TODO Auto-generated method stub
                      return null;
                  }
          
                  @Override
                  public Object getFieldValue(String field) {
                      // TODO Auto-generated method stub
                      return null;
                  }
          
                  @Override
                  public Class getFieldType(String field) {
                      // TODO Auto-generated method stub
                      return null;
                  }
          
                  @Override
                  public List<FieldError> getFieldErrors(String field) {
                      // TODO Auto-generated method stub
                      return null;
                  }
          
                  @Override
                  public List<FieldError> getFieldErrors() {
                      // TODO Auto-generated method stub
                      return null;
                  }
          
                  @Override
                  public int getFieldErrorCount(String field) {
                      // TODO Auto-generated method stub
                      return 0;
                  }
          
                  @Override
                  public int getFieldErrorCount() {
                      // TODO Auto-generated method stub
                      return 0;
                  }
          
                  @Override
                  public FieldError getFieldError(String field) {
                      // TODO Auto-generated method stub
                      return null;
                  }
          
                  @Override
                  public FieldError getFieldError() {
                      // TODO Auto-generated method stub
                      return null;
                  }
          
                  @Override
                  public int getErrorCount() {
                      // TODO Auto-generated method stub
                      return 0;
                  }
          
                  @Override
                  public List<ObjectError> getAllErrors() {
                      // TODO Auto-generated method stub
                      return null;
                  }
          
                  @Override
                  public void addAllErrors(Errors errors) {
                      // TODO Auto-generated method stub
          
                  }
              } );
          

          【讨论】:

          • 正是我寻找替代方案的原因
          • 您始终可以创建自己的 MyError 类(作为内部类或包私有甚至公共类)并在您想使用它时实例化它。我还编辑了我的回复以包含一个指向 Spring 文档的链接,其中列出了实现 Errors 接口的其他 Spring 类
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-11-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多