복붙노트

[SPRING] @ModelAttribute 및 추상 클래스

SPRING

@ModelAttribute 및 추상 클래스

비슷한 질문이 있다는 것을 알고 있습니다. 그들에 주어진 예제들은 너무 단편적이며 불분명하다.

POST를 보내는 페이지의 양식을 통해 엔티티를 편집해야합니다. 표준 메소드는 컨트롤러의 메소드로 @ModelAttribute 및 validator와 함께 매개 변수를 사용합니다. 하나의 양식이 추상 클래스의 일부 서브 클래스를 제공하는 경우, 필수 필드의 생성에는 문제가 없지만 컨트롤러에는 문제가 있습니다.

내가 알기에, @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을 가져 와서 변환기에 넘겨주는 메서드이며, 자동 바인딩 메커니즘을 통해 컨트롤러의 메서드 결과를 반환합니다.

도와주세요, 제발.

해결법

  1. ==============================

    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이 model 속성을 생성 할 필요가있을 때, 속성이 이미 존재하는지 검사한다. 존재하지 않고 일치하는 이름의 요청 매개 변수가없는 경우 매개 변수 클래스의 기본 생성자를 사용하여 새 객체를 만듭니다.

    존재하고 인수 유형과 일치하면 요청 매개 변수를 바인드합니다. 호환되지 않거나 동일한 이름의 요청 매개 변수가 사용 가능한 경우 현재 값을 필수 유형으로 변환 할 수있는 변환기를 찾습니다

    변환이 성공하면 요청 매개 변수를 결과에 바인딩합니다. 그렇지 않으면 예외를 발생시킵니다.

    귀하의 경우 person 속성은 String으로 보내집니다. Spring은 그것을 Person으로 변환하려고 시도 할 것이다. 당신의 PersonConverter를 선택하여 바인딩하기 전에 적절한 서브 클래스로의 변환을 수행합니다.

  2. from https://stackoverflow.com/questions/37300586/modelattribute-and-abstract-class by cc-by-sa and MIT license