Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Data binding spring mvc绑定到两个具有相同字段的对象中_Data Binding_Spring Mvc - Fatal编程技术网

Data binding spring mvc绑定到两个具有相同字段的对象中

Data binding spring mvc绑定到两个具有相同字段的对象中,data-binding,spring-mvc,Data Binding,Spring Mvc,我提交了一份表格,假设该表格包含 <input name="address" ..> 显然billingAddress不会绑定到billingAddress中的地址 假设我在地址和账单地址中都有多个相同的字段,但在表单上,我在账单输入前加上了账单前缀,即billingFirstName、billingLastName等 是否有一些优雅的方法可以绑定到BillingAddress,以便重复使用以解决类似问题? (或者有没有比我提出的更好的方法来解决这个问题?如果你想使用多个Model

我提交了一份表格,假设该表格包含

<input name="address" ..>
显然
billingAddress
不会绑定到
billingAddress
中的地址

假设我在
地址
账单地址
中都有多个相同的字段,但在表单上,我在账单输入前加上了账单前缀,即billingFirstName、billingLastName等

是否有一些优雅的方法可以绑定到
BillingAddress
,以便重复使用以解决类似问题?

(或者有没有比我提出的更好的方法来解决这个问题?

如果你想使用多个ModelAttribute,你必须创建一个包装器对象,它包含每个ModelAttribute的一个实例。在您的例子中,我将创建一个名为“FormModel”的包装器对象,它包含一个Address实例和一个BillingAddress实例

class FormModel {
  private Address address;
  private BillingAddress billingAddress;

  // Getters and Setters
}
现在使用FormModel作为ModelAttribute。 在表单中,您可以定义输入元素,如:

<input name="address.address" ..>
<input name="billingAddress.address" ..>
如果对Address和BillingAddress使用自定义验证器,则还必须创建一个FormModelValidator,该验证器调用AddressValidator和BillingAddressValidator:

public class FormModelValidator implements Validator {

    private final AddressValidator addressValidator;

    private final BillingAddressValidator billingAddressValidator;

    public FormModelValidator(AddressValidator addressValidator,
            BillingAddressValidator billingAddressValidator) {
        this.addressValidator = addressValidator;
        this.billingAddressValidator = billingAddressValidator;
    }

    public boolean supports(Class<?> clazz) {
        return FormModel.class.equals(clazz);
    }

    public void validate(Object target, Errors errors) {
        FormModel formModel = (FormModel) target;
        try {
            errors.pushNestedPath("address");
            ValidationUtils.invokeValidator(this.addressValidator,
                    formModel.getAddress(), errors);
        } finally {
            errors.popNestedPath();
        }
        try {
            errors.pushNestedPath("billingAddress");
            ValidationUtils.invokeValidator(this.billingAddressValidator,
                    formModel.getBillingAddress(), errors);
        } finally {
            errors.popNestedPath();
        }
    }

}
公共类FormModelValidator实现验证程序{
专用最终地址验证器地址验证器;
专用最终计费地址验证程序计费地址验证程序;
公共FormModelValidator(AddressValidator AddressValidator,
账单地址验证程序账单地址验证程序){
this.addressValidator=addressValidator;
this.billingAddressValidator=billingAddressValidator;
}
公共布尔支持(类clazz){
返回FormModel.class.equals(clazz);
}
公共无效验证(对象目标、错误){
FormModel FormModel=(FormModel)目标;
试一试{
错误。pushNestedPath(“地址”);
ValidationUtils.invokeValidator(this.addressValidator,
formModel.getAddress(),错误);
}最后{
错误。popNestedPath();
}
试一试{
错误。pushNestedPath(“billingAddress”);
ValidationUtils.invokeValidator(this.billingAddressValidator,
formModel.getBillingAddress(),错误);
}最后{
错误。popNestedPath();
}
}
}

这给了我一个新问题;)我尝试使用自己的验证器验证BillingAddress和Address对象,但BindingResult对象引用FormModel对象,因此无法从其上的其他2个对象中找到任何错误字段。如果我没有弄错,您可以使用Address和BillingAddress的自定义验证器。在这种情况下,您必须创建一个FormModelValidator,它调用您的自定义验证器。我在上面的回答中加了一个例子。
<input name="address.address" ..>
<input name="billingAddress.address" ..>
@RequestMapping(value = "/save", method = RequestMethod.POST)
public String save(Model model, @ModelAttribute() FormModel formModel) {
   // process formModel.getAddress()
   // process formModel.getBillingAddress()

   return "redirect:home";
}
public class FormModelValidator implements Validator {

    private final AddressValidator addressValidator;

    private final BillingAddressValidator billingAddressValidator;

    public FormModelValidator(AddressValidator addressValidator,
            BillingAddressValidator billingAddressValidator) {
        this.addressValidator = addressValidator;
        this.billingAddressValidator = billingAddressValidator;
    }

    public boolean supports(Class<?> clazz) {
        return FormModel.class.equals(clazz);
    }

    public void validate(Object target, Errors errors) {
        FormModel formModel = (FormModel) target;
        try {
            errors.pushNestedPath("address");
            ValidationUtils.invokeValidator(this.addressValidator,
                    formModel.getAddress(), errors);
        } finally {
            errors.popNestedPath();
        }
        try {
            errors.pushNestedPath("billingAddress");
            ValidationUtils.invokeValidator(this.billingAddressValidator,
                    formModel.getBillingAddress(), errors);
        } finally {
            errors.popNestedPath();
        }
    }

}