[SPRING] Spring MVC 3에서 양식 제출 - 설명
SPRINGSpring MVC 3에서 양식 제출 - 설명
Spring 3 MVC에서 폼을 어떻게 제출하는지 이해하는데 문제가 있습니다.
내가하고 싶은 일은 사용자 이름을 가져다가 컨트롤러에 표시하는 컨트롤러를 만드는 것입니다. 그리고 어떻게 든 나는 그것을 해냈지만 실제로 어떻게 작동하는지 이해하지 못합니다. 그래서..
나는 다음과 같은 형태를 가지고있다.
<form:form method="post" modelAttribute="person">
<form:label path="firstName">First name</form:label>
<form:input path="firstName" />
<br />
<form:label path="lastName">Last name</form:label>
<form:input path="lastName" />
<br />
<input type="submit" value="Submit" />
</form:form>
나는 또한 다음과 같은 컨트롤러를 가지고있다 :
@Controller
public class HomeController {
@RequestMapping(value = "/", method = RequestMethod.GET)
public String showHelloPage(Model model) {
model.addAttribute("person", new Person());
return "home";
}
@RequestMapping(value = "/", method = RequestMethod.POST)
public String sayHello(Person person, Model model) {
model.addAttribute("person", person);
return "home";
}
}
사용자에게 환영 메시지를 표시하려면 JSP 페이지에서 다음 코드를 사용한다.
<c:if test="${not empty person.firstName and not empty person.lastName}">
Hello ${person.firstName} ${person.lastName}!
</c:if>
그리고 그것은 작동합니다 (XML 구성 파일은 문제와 관련이 없으므로 생략합니다).
폼의 "modelAttribute"애트리뷰트가 입력 값으로 채워 져야하는 bean 변수를 가리킨다 고 생각했다. 그러나 외모는 매우 다른 방식으로 작용합니다. 내가 선을 제거하면
model.addAttribute("person", new Person());
"showHelloPage"메서드에서 (공통적 인) 예외 "BindingResult도 아니고 ..."이 나타납니다.
또한 처음에는 "sayHello"메소드가 다음과 같이 보입니다.
(...)
public String sayHello(@ModelAttribute("person") Person person, Model model) {
(...)
제 말은 "ModelAttribute"주석이 있다는 것입니다. 내가 읽은 튜토리얼에서는 항상 존재했기 때문에 덧붙였다. 하지만 제거한 후에 모든 것이 잘 돌아갔습니다.
그래서 내 질문은 - "ModelAttribute"anonnatation의 사용은 무엇입니까? 양식에서 "modelAttribute"특성을 생략하는 것이 어떤 방법입니까? 그리고 두 번째 부분은 양식을 만드는 방법 (어쩌면 몇 가지 주석)이 입력 값을 적절한 bean의 속성 (메소드 매개 변수로 선언 됨)에 자동으로 바인딩하는 방법은 무엇입니까? 폼을 보내기 전에 빈 빈을 추가 할 필요없이 (지금해야만하기 때문에).
답장을 보내 주셔서 감사합니다 (이미 읽었으므로 Spring의 설명서 링크는 아닙니다).
해결법
-
==============================
1.이 경우 @ModelAttribute 주석은 Spring이 모델 속성으로 추가해야하는 객체를 식별하는 데 사용됩니다. 모델 속성은 HttpServletRequest 속성의 추상화입니다. 기본적으로 HttpServletRequest 속성으로 들어가는 열쇠로 식별되는 객체입니다. Model # addAttribute (String, Object)를 사용하여 속성을 수동으로 추가하거나 @ ModelAttribute 주석이있는 메소드가 있거나 @ModelAttribute로 메소드 매개 변수에 주석을 추가하여이 작업을 수행 할 수 있습니다.
이 경우 @ModelAttribute 주석은 Spring이 모델 속성으로 추가해야하는 객체를 식별하는 데 사용됩니다. 모델 속성은 HttpServletRequest 속성의 추상화입니다. 기본적으로 HttpServletRequest 속성으로 들어가는 열쇠로 식별되는 객체입니다. Model # addAttribute (String, Object)를 사용하여 속성을 수동으로 추가하거나 @ ModelAttribute 주석이있는 메소드가 있거나 @ModelAttribute로 메소드 매개 변수에 주석을 추가하여이 작업을 수행 할 수 있습니다.
이해해야 할 것은 Spring이 처리기 메소드 매개 변수를 해결하고 인수를 주입하는 방법입니다. HandlerMethodArgumentResolver 인터페이스를 사용하여 그렇게합니다. 다수의 구현 클래스 (javadoc 참조)가 있으며 각각은 Spring이 리플렉션을 통해 핸들러 메소드를 호출 (invoke)하는 데 사용할 인수를 반환하여 resolveArgument ()를 수행 할 책임이 있습니다. Spring은 HandlerMethodArgumentResolver supportsParameter () 메소드가 특정 매개 변수에 대해 true를 리턴하는 경우에만 resolveArgument () 메소드를 호출합니다.
문제의 HandlerMethodArgumentResolver 구현체는 ModelAttributeMethodProcessor에서 확장 한 ServletModelAttributeMethodProcessor이다.
Spring (3.2)은이 HandlerMethodArgumentResolver와 다른 것을 등록 할 것이다.
private List<HandlerMethodArgumentResolver> getDefaultArgumentResolvers() { List<HandlerMethodArgumentResolver> resolvers = new ArrayList<HandlerMethodArgumentResolver>(); // Annotation-based argument resolution resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), false)); resolvers.add(new RequestParamMapMethodArgumentResolver()); resolvers.add(new PathVariableMethodArgumentResolver()); resolvers.add(new ServletModelAttributeMethodProcessor(false)); resolvers.add(new RequestResponseBodyMethodProcessor(getMessageConverters())); resolvers.add(new RequestPartMethodArgumentResolver(getMessageConverters())); resolvers.add(new RequestHeaderMethodArgumentResolver(getBeanFactory())); resolvers.add(new RequestHeaderMapMethodArgumentResolver()); resolvers.add(new ServletCookieValueMethodArgumentResolver(getBeanFactory())); resolvers.add(new ExpressionValueMethodArgumentResolver(getBeanFactory())); // Type-based argument resolution resolvers.add(new ServletRequestMethodArgumentResolver()); resolvers.add(new ServletResponseMethodArgumentResolver()); resolvers.add(new HttpEntityMethodProcessor(getMessageConverters())); resolvers.add(new RedirectAttributesMethodArgumentResolver()); resolvers.add(new ModelMethodProcessor()); resolvers.add(new MapMethodProcessor()); resolvers.add(new ErrorsMethodArgumentResolver()); resolvers.add(new SessionStatusMethodArgumentResolver()); resolvers.add(new UriComponentsBuilderMethodArgumentResolver()); // Custom arguments if (getCustomArgumentResolvers() != null) { resolvers.addAll(getCustomArgumentResolvers()); } // Catch-all resolvers.add(new RequestParamMethodArgumentResolver(getBeanFactory(), true)); resolvers.add(new ServletModelAttributeMethodProcessor(true)); return resolvers; }
Spring이 핸들러 메소드를 호출 할 필요가있을 때, 매개 변수 유형과 위의 목록을 반복하여 supportsParameter ()를 지원하는 첫 번째 메소드를 사용합니다.
ServletModelAttributeMethodProcessor의 두 인스턴스가 추가됩니다 (// 모든 주석을 catch 한 후에 하나). ModelAttributeMethodProcessor에는 @ModelAttribute를 찾아야하는지 여부를 알려주는 annotationNotRequired 필드가 있습니다. 첫 번째 인스턴스는 @ModelAttribute를 찾아야하며 두 번째 인스턴스는 그렇지 않습니다. Spring은 독자적인 HandlerMethodArgumentResolver 인스턴스를 등록 할 수 있도록 이것을한다. // Custom arguments 주석을 보라.
특히
@RequestMapping(value = "/", method = RequestMethod.POST) public String sayHello(Person person, Model model) { model.addAttribute("person", person); return "home"; }
이 경우 Person 매개 변수에 주석을 달았는지 여부는 중요하지 않습니다. ModelAttributeMethodProcessor는이를 해결하고 양식 필드를 바인딩합니다. 요청 매개 변수를 인스턴스의 필드에 추가합니다. ModelAttributeMethodProcessor 클래스가이를 처리 할 때 모델에 추가 할 필요조차 없습니다.
showHelloPage () 메소드에서
model.addAttribute("person", new Person());
from https://stackoverflow.com/questions/18944627/form-submit-in-spring-mvc-3-explanation by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] @Test 이후 롤백 트랜잭션 (0) | 2018.12.09 |
---|---|
[SPRING] OAuth2RestTemplate을 사용하는 방법? (0) | 2018.12.09 |
[SPRING] Spring의 설정 파일에서 Bean의 속성 Enum 값을 할당하는 방법은 무엇입니까? (0) | 2018.12.09 |
[SPRING] Log4J를 봄으로 초기화 하시겠습니까? (0) | 2018.12.09 |
[SPRING] org.hibernate.proxy.pojo.javassist.Javassist 클래스에 대한 serializer가 없습니다. (0) | 2018.12.09 |