Я знаю, что были похожие вопросы. Приведенные в них примеры слишком фрагментарны и неясны.@ModelAttribute и abstract class
Мне нужно отредактировать объекты через форму на странице, которая отправляет POST. Стандартный метод - это метод в контроллере, который использует параметр с @ModelAttribute и валидатор. Если одна форма обслуживает некоторый подкласс абстрактного класса, нет проблем с генерацией необходимых полей, но в контроллере есть проблема.
Как я понимаю, @ModelAttribute работает таким образом: он инициализирует желаемый класс объекта и затем собирает его поля параметров запроса. Конечно, если объект является абстрактным классом, его нельзя инициализировать. Поэтому в форме есть поле, которое укажет, какой подкласс инициализируется. Затем нам нужен мир кода, который будет читать этот атрибут и инициализировать правильный подкласс. Что это должно быть? Я видел фрагментарные примеры о конвертере, PrepertyEditor, WebDataBinder, но сложно собрать все вместе.
So. Есть следующая иерархия:
public abstract class Person {role, name, email, password ...}
public class Student extends Person {}
public class Lecturer extends Person {}
Существует контроллер и методы в нем:
@RequestMapping (Path = "/ persons/uid {personId}/edit",
method = RequestMethod.GET)
public String editPerson (@PathVariable Integer personId, Model model) {
Person find = personDAO.read (personId);
model.addAttribute ("person", find);
return "editPerson";
}
@RequestMapping (Path = "/ persons/uid {personId}/edit",
method = RequestMethod.POST)
public String editPersonPost (@PathVariable Integer personId,
@Valid @ModelAttribute ("Person") Person person,
BindingResult result) {
if (result.hasErrors()) return "editPerson error = true?";
personDAO.update (person);
return "redirect:/persons/uid" + personId + "saved = true?";
}
И есть JSP с формой:
<%@ page language="java" contentType="text/html; charset=UTF-8"
pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@taglib uri="http://www.springframework.org/tags/form" prefix="form"%>
<h1>${person.name}</h1>
<form:form action="edit" method="post" commandName="person">
<input type="hidden" value="${person.role}" name="person_type" />
<table>
<tr>
<td>Password</td>
<td><form:input path="httpAuth.password" type="password"/></td>
<td><form:errors path="httpAuth.password" cssClass="error"></form:errors></td>
</tr>
<tr>
<td>Email</td>
<td><form:input path="email" /></td>
<td><form:errors path="email" cssClass="error"></form:errors></td>
</tr>
<tr>
<td></td>
<td><input type="submit" value="Save"></td>
<td></td>
</tr>
</table>
</form:form>
Кроме того, преобразователь имеет было написано, но я сомневаюсь, что это необходимо, или же это сделать (наследующий другой класс ...)
public class PersonConverter implements Converter <String, Person> {
public Person convert (String personType) {
Person person = null;
switch (personType) {
case "Student":
person = new Student();
break;
case "Lecturer":
person = new Lecturer();
break;
default:
throw new IllegalArgumentException (
"Unknown person type:" + personType);
}
return person;
}}
Который зарегистрирован ConversionService
<bean class="org.springframework.context.support.ConversionServiceFactoryBean"
id="theConversionService">
<property name="converters">
<list>
<bean class="schedule.service.PersonConverter"></bean>
</list>
</property>
</bean>
<mvc:annotation-driven conversion-service="theConversionService" validator="validator"/>
Тем не менее, что-то отсутствует, то есть метод, который будет принимать person_type
из параметров запроса и передать его в преобразователь, и он будет возвращать результат метода контроллера с помощью механизмы автоматического связывания.
Помогите мне пожалуйста.