출처 : http://anarch.tistory.com/98
Spring2.5의 Annotation Configuration의 도입에 가장 큰 영향을 받는 곳이 spring-mvc이다. 특히 AbstractController이나 SimpleFormController의 구체적인 상속 없이 URL과 객체가 매핑이 가능하다.
- @Controller
@RequestMapping("/hello.html")
public class HelloWorldController {
@RequestMapping(method=RequestMethod.GET)
public String hello(ModelMap model) {
return "hello";
}
}
이전 ModelAndView에서 ModelMap으로 Model과 View을 나누었다. ModelMap을 보면 Map 인터페이스가 가지고 있는 메소드를 가지고 있다. 즉 Map 인터페이스의 구현체중 하나(LinkedHashMap)를 상속했다.
SpringMVC의 UrlMapping에서 하나 불만 사항이 있다면 package개념이 없다는 점이다. WebWork/Struts2의 경우 패캐지 태그안에 하나의 네임스페이스처럼 구성할수가 있는데.. 많은 url mapping이 존재하게 되면 package개념(관례적으로라도) 구성하게 되는데 이런 부분이 없는게 아쉽다. 가령
- @Controller
@RequestMapping("/hello")
public class HelloWorldController {
@RequestMapping("/world.html")
public String hello(ModelMap model) {
return "hello/world";
}
}
이렇게 구성해도 Exception은 발생하지만 않지만 Mapping을 찾지 못한다. 버그인지도 :-)
또 이렇게 Annotation 기반으로 mapping을 할때 고민되는 점이 Interceptor부분이다. XML의 경우 각각 Interceptor마다 UrlHandlerMapping 빈을 만들어서 해결했지만, Annotation 기반의 매핑의 경우 불가능하다. 결국 생각해 보면,
<bean class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping">
<property name="interceptors">
<bean class="kata.springmvc.interceptors.UrlPatternMatchingInterceptor" >- <property name="allowUrlPatterns">
<list>
<value>/app/board/*</value>
<value>/app/client/*</value>
</props>
</property>
</bean>
</property>
</bean>
처럼 UrlPatternMatchingInterceptor을 하나 만들어서 (상속해서) handle하도록 해야 할듯 하다.
SpringMVC에서 가장 많이 쓰는 Controller 구현체는 대개 AbstractController과 SimpleFormController,MultiActionController등이 될듯 한데. Annotation기반 설정은 특정 Controller 구현체를 상속받지 않으므로 (더군다나 Servlet API과도 decoupling되는데.)
SimpleFormController 처럼 HTTP Method가 GET 일경우와 POST일 경우 Controller의 움직임을 나누고 싶다면
- @Controller
@RequestMapping("/board_form.html")
public class BoardFormController {
@RequestMapping(method = RequestMethod.GET)
public String onForm(ModelMap model) {
Board board = new Board();
model.addAttribute("board", board);
return "form";
}
@RequestMapping(method = RequestMethod.POST)
public String onSubmit( - @ModelAttribute("board") Board board,BindingResult result,ModelMap model) {
return "goto_list";
}
}
으로 간단히 구성된다. initBinder의 경우 annotation으로 존재하고 onValidate같은 경우는 onSubmit에서 메소드를 호출하면 될듯 하다(흐름을 강제적으로 제약되지 않는다.) SimpleFormController을 쓰면 기본적인 흐름에 대한 필요한 요소만 채워준다는 느낌이 들었는데(Framework과 대화한다고 할까?) 이런 강제적인 부분이 사라진듯 하지만, SimpleFormController에서 약간만 예외적인 흐름을
구성하려고 하면 복잡함이 다가오는 걸 볼때, 이런 간단한 흐름만 제공하는것도 맞을 것 같다.
MultiActionController은 좀더 간단한데,
- @RequestMapping("/multi/list.html")
public String list(ModelMap model) {
model.addAttribute("test", new String("test....."));
return "list";
}
당연하겠지만 메소드의 return이 void 일 경우 CoC으로 메소드 이름으로 view을 찾는다.
특히 Servlet API을 직접 사용하지 않아도 되는 @RequestParam,@RequestAttribute,@SessionAttributes등이 있다.
이 부분에서 약간 불만인 점은 @RequestAttribute("board") Board board 같은 Form을 Command객체 하나로만 Binding된다는 점이다. 폼이 하나의 객체로만 환원 되는 일이 얼마나 될까. 복잡한 폼일수록 여러 객체를 한 화면에서 Form에 그릴 일이 많아지는데
말이다. 물롬 FormBean처럼 Command 객체를 만들고 Model을 Composite하면 해결되는 문제이긴 하지만.
만일 Form Tag에서
- <from:input path="board.title" ...
- <form:input path="menu.title" ...
- public String list(@ModelAttribute("board")Board board,@RequestAttribute("menu")Menu menu...
이러게 되면 어떨까? '_' 되는데 모르는 걸수도 있겠다. .이 부분은 그냥 나의 짧은 생각.. :-) (해보지 않았음)
약간 2시간 정도면 간단한게 알아 볼수 있을 꺼라 생각했지만..한 4시간은 쓴거 같다.. T_T 사실 tomcat 설정도 기억 안나서 servlet 띠우는 거만으로 삽질한거 보면.. 대충보면 쉬워 보이는 일이라도 막상 하면 쉬운 일은 하나도 없는거 같다.
기술을 하나 제대로 배운다는게 결코 쉬운 일이 아니라는 생각이 든다. 단지 이런 사용법을 안다고 어떤 기술의 가지고 있다고 할수가 없는 거 같다. 배면의 움직임을 이해하고 습득하는게 중요하다고 생각되기도 하지만. 어느 도메인을 추구하는지에 따라 해답을 달라 질듯 하다. Over Layered Architecture... Layered Developer? :-)
'백엔드 프레임워크 & 언어' 카테고리의 다른 글
01-자바스크립트(JavaScript)의 개요 (0) | 2011.01.12 |
---|---|
Spring 2.5 annotation 기반 설정 (0) | 2011.01.09 |
@Controller, @RequestMapping - Annotation in Spring(어노테이션을 사용한 컨트롤러 구현) (0) | 2011.01.09 |
Spring MVC Annotation기반으로 사용시 URL기반 요청 문제점 해결방법 (0) | 2011.01.09 |
InternalResourceViewResovler 설정 (0) | 2011.01.09 |