Spring mvc communicates with two objects that have the same fields
I will submit the form, say this form contains
<input name="address" ..> and
<input name="billingAddress" ..> I have 2 objects that I need to bind to:
class Address { String address; .. } class BillingAddress { String address; .. } apparently billingAddress does not bind to the address in billingAddress without any magic.
says that I have several identical fields in both Address and billingAddress , but in the form I have a prefix of billing inputs with billing, i.e. billingFirstName, billingLastName, etc.
Is there any elegant way to bind to billingAddress that I can use for similar problems?
(or is there a better way to solve this, what did I come up with?)
If you use more than one ModelAttribute attribute, you need to create a wrapper object that contains an instance of each ModelAttribute attribute. In your case, I will create a wrapper object named "FormModel" that contains an instance of Address and an instance of BillingAddress.
class FormModel { private Address address; private BillingAddress billingAddress; // Getters and Setters } Now use FormModel as your ModelAttribute. In your form, you can define your input elements, for example:
<input name="address.address" ..> <input name="billingAddress.address" ..> Controller:
@RequestMapping(value = "/save", method = RequestMethod.POST) public String save(Model model, @ModelAttribute() FormModel formModel) { // process formModel.getAddress() // process formModel.getBillingAddress() return "redirect:home"; } If you use custom validators for Address and BillingAddress, you also need to create a FormModelValidator that calls AddressValidator and 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(); } } }