【问题标题】:Validate to see if form has changed验证以查看表单是否已更改
【发布时间】:2011-08-09 05:50:33
【问题描述】:

我正在编写一个验证器,它需要测试弹簧表单对象是否已更改。

在验证器中,如果没有对表单进行任何更改,则应显示错误。

是否有弹簧机制可以做到这一点?

这是因为在我提交时进行了非常昂贵的 webservice 更新调用,如果没有进行任何更改,我需要阻止 webservice 调用。

干杯。

【问题讨论】:

  • 你是指JSR 303 Validator,还是Spring Validator (org.springframework.validation.Validator)?
  • Mitch 在我的团队中,他指的是 Spring Validator。
  • 像这样:将对象绑定到表单,在绑定点,获取所有字段的副本或哈希。要验证,将副本与字段进行比较或获取所有字段的新哈希,如果字段/哈希相同则给出错误。

标签: java spring spring-webflow


【解决方案1】:

覆盖您的 hashCode() 函数以确保在表单值更改时返回不同的值。保存函数的返回值并测试它是否改变了。

public class Person {
  String first;
  String last;
  int prevHash;
  @Override
  public int hashCode() {
    // does not include the value of currHash
    String stringHash = String.format("%1$-29s%2$-29s", first,last);
    return stringHash.hashCode();
  }
}

public class PersonValidator  implements Validator {
  public void validate(Object obj, Errors e) {
    Person p = (Person) obj;
    if (p.hashCode() == p.getPrevHash()) {
      e.reject("person", "unchanged");
    } 
  }
  ...
}

我认为没有 Spring 提供的验证测试来检查表单支持对象是否已更改

请注意,在允许用户提交表单之前,您可以在客户端执行额外的测试。

【讨论】:

    【解决方案2】:

    我不知道有任何内置的 Spring 机制来处理这个问题。我会保存原始对象和修改后的对象的副本。我会适当地覆盖 Form.equals() 方法(如果所有字段都是原语/字符串,则可能委托给 org.apache.commons.lang.builder.EqualsBuilder.reflectionEquals())并使用 Form.equals()检查表单是否已更改。

    我在这里看到了两个不同的响应,这意味着覆盖“hashCode”方法是一个好方法。 hashCode() 的合同中没有保证不等式,这可能会导致问题。一定要覆盖equals()。当然,哈希冲突的可能性是万亿分之一,但是当您尝试检查两个对象是否不同时,仅依赖 hashCode() 是一种糟糕的设计。

    【讨论】:

    • 好点。更好的方法可能是将原始对象存储在会话中,如果您的 equals() 方法为您提供该信息,则测试是否相等,或者编写一个单独的方法来比较特定字段的更改。
    【解决方案3】:

    根据客户端检查表单是否已更改,尝试不同的方法。 启动表单用户界面/jQuery:

       $(document).ready(function() {
            var isFormChanged = false;
            var isConfirmed = false;
            $("form :input").change(function() {
                console.log($(this).attr('name'));
                isFormChanged = true;
            });
    
            $("#storeForm").submit(function(event) {
                if (!isConfirmed) {
                    event.preventDefault();
                }
                if (isFormChanged) {
                    console.log("Form has changed");
                    $(":submit").addClass("btn-danger");
                    $(":submit").text("Confirm");
                    isConfirmed = true;
                }
            });
        });
    

    您还可以在表单中设置隐藏字段以将信息发送回 Spring 以在服务器端再次检查所有这些信息。它比将所有表单数据推送回服务器只是为了检查是否每次都发生了变化要快。

    【讨论】:

      猜你喜欢
      • 2012-05-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-18
      • 2012-03-16
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多