【问题标题】:@ModelAttribute and abstract class@ModelAttribute 和抽象类
【发布时间】:2016-05-18 13:07:51
【问题描述】:

我知道有类似的问题。里面给出的例子太片面了,不清楚。

我需要通过发送 POST 的页面上的表单来编辑实体。标准方法是控制器中的方法使用带有@ModelAttribute 和验证器的参数。如果一个表单服务于某个抽象类的某个子类,那么生成必要字段就没有问题,但是控制器有问题。

据我了解,@ModelAttribute 是这样工作的:它初始化所需的对象类,然后收集他的请求参数字段。当然,如果对象是抽象类,是不能初始化的。因此,表单有一个字段将指示要初始化的子类。接下来,我们需要和平的代码,它将读取此属性并初始化正确的子类。应该是什么?我看到了关于 Converter、PrepertyEditor、WebDataBinder 的零碎示例,但很难将所有内容放在一起。

所以。有以下层次结构:

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并将其提供给转换器的方法,它将通过自动绑定机制将方法的结果返回给控制器。

请帮帮我。

【问题讨论】:

    标签: spring spring-mvc inheritance abstract-class


    【解决方案1】:

    你只需要确保下面的元素

    <input type="hidden" value="${person.role}" name="person_type" />
    

    已将其命名属性更改为 person

    <input type="hidden" value="${person.role}" name="person" />
    

    使其与控制器中的模型属性匹配

    public String editPersonPost (@PathVariable Integer personId,
            @Valid @ModelAttribute ( "person") Person person,
            BindingResult result)
    

    这就是它的工作原理。

    当收到请求并且 Spring 需要创建模型属性时,它会检查该属性是否已经存在。如果它不存在并且没有匹配名称的请求参数,它会使用参数类的默认构造函数创建一个新对象

    如果它存在并且匹配参数类型,它会继续绑定请求参数。如果不兼容或有同名请求参数可用,它会尝试找到能够将当前值转换为所需类型的转换器

    如果转换成功,则将请求参数绑定到结果,否则抛出异常

    在您的情况下,person 属性作为字符串发送。 Spring 将尝试将其转换为 Person。它会在绑定之前选择您的 PersonConverter 来转换为适当的子类

    【讨论】:

      猜你喜欢
      • 2011-11-12
      • 1970-01-01
      • 2017-11-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-02-19
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多