Вы просто создадите новый класс, содержащий все свойства, необходимые для формы, и будете использовать его в качестве атрибута модели для вашей формы. При получении вызова вы также можете использовать этот тип. Spring автоматически свяжет свойства для вас. Вам также следует рассмотреть возможность использования аннотаций проверки JSR-303.
Общий подход заключается в загрузке всех необходимых объектов для создания объекта поддержки формы по запросу GET. Затем вы помещаете этот объект в модель. По запросу POST / PUT вы должны восстановить фактические объекты, к которым вы прикоснулись. Обычно вы загружаете их снова и применяете к ним новые переданные частичные данные.
В целом, было бы неплохо создать выделенный компонент для обработки этого поведения при сборке, чтобы вы не загрязняли контроллер этим кодом.
/**
* Prepares the form by setting up a custom form backing object.
*/
@RequestMapping(value = "account/{id}", method = GET)
public String processGet(@PathVariable("id") Long id, Model model) {
Account account = accountService.getAccount(id);
return prepareForm(dtoAssembler.createFormFor(account), model);
}
/**
* Process form submission. Uses JSR-303 validation and explicit error
* handling.
*/
@RequestMapping(value = "account/{id}", method = PUT)
public String processGet(@ModelAttribute("accountForm") @Valid AccountForm form, Errors errors, Model model) {
if (errors.hasErrors()) {
return prepareForm(form, model);
}
Account account = accountService.getAccount(form.getId());
accountService.save(dtoAssembler.applyData(account, form));
return "redirect:/accounts";
}
/**
* Populates the given {@code Model} with the given {@code AccountForm}
* and returns the view to show the form.
*/
private String prepareForm(AccountForm form, Model model) {
model.addAttribute("accountForm", form);
return "account";
}
Я просто так написал здесь, чтобы подчеркнуть, что происходит. В реальном сценарии я бы, вероятно, позволил DtoAssembler выполнять всю работу со службой (поэтому я вставил бы службу в ассемблер).
Вероятно, целесообразно упростить передачу данных из DTO в объект домена с помощью Dozer, BeanUtils или чего-то подобного.