Spring MVC & Java1.4 tip
From JCFWiKi
Copyright © 2008 Daewoo Information Systems Co., Ltd. |
|
목차 |
[편집] 설정파일의 간략화
- Arid와 ControllerClassNameHandlerMapping의 조합으로 Annotation을 사용할 수 없는 Java 1.4 환경에서 번거로울 수 있는 web controller의 설정을 줄이고, Controller 클래스의 수를 줄임으로써 개발의 편이성을 높일 수 있다.
- 다음은 블로그 예제에 대하여 Java 1.4에서 SpringMVC를 사용하였을 때, arid와 coc를 적용하였을 때, Jave 5.0+에서 annotation을 사용하였을 때를 비교한 것이다.
| 코드 | Blog(Original) | Blog(arid+coc) | Blog(java5.0+ annotation) |
| blog-servlet.xml | View Resolver bean 등록, 각 Controller-url 맵핑 bean 등록 |
Arid, mapping handler bean, view name translator bean 등록 |
component scan, view resolver bean 등록 |
| 약 30 lines | 약 20 lines | 약 15 lines | |
| Controller | blog.web.CreateBlogFormController, blog.web.EditBlogFormController, blog.web.FindBlogController |
blog.web.BlogController | blog.web.BlogController |
| MultiActionController, SimpleFormController 상속 |
MultiActionController 상속 | @Controller 지정 |
|
[편집] Arid
- <arid:define-bean />
- 클래스 및 클래스의 멤버변수를 bean으로 등록해주는 역할을 한다.
- arid 사용하기
- arid-framework.jar와 aspectjweaver.jar 클래스 파일이 필요하다.
- beans 정의에 arid를 추가해야 한다.
- web controller는 xxx-servlet.xml에서 설정한다.
- controller 클래스 멤버변수의 set 메소드의 작성이 필요하다.
@Autowired == <arid:define-bean /> + setXXX()
<?xml version="1.0" encoding="UTF-8" ?> <beans xmlns:arid="http://chrisrichardson.net/schema/arid" xsi:schemaLocation="http://chrisrichardson.net/schema/arid http://chrisrichardson.net/schema/arid.xsd" > <!-- auto registration and wiring of beans --> <arid:define-beans package="edu.blog" pattern="*..web.*Controller" autowire="byName"/> </beans>
- 한계
- Spring MVC annotation 중 @Autowired를 커버할 수 있지만, Controller, RequestMapping 등의 다른 annotation을 대체할 순 없다.
|
[편집] ControllerClassNameHandlerMapping
- url과 클래스 맵핑의 관계를 자동으로 지정해주는 Handler Mapper이다.
- Conversion of Configuration(CoC)의 개념이다.
- ControllerClassNameHandlerMapping을 적용하지 않은 경우 Controller class에 대한 url을 직접 지정해주어야 한다.
<bean name="/findBlogs.do" class="blog.web.FindBlogController"> <property name="blogService" ref="blogService" /> </bean>
- ControllerClassNameHandlerMapping을 적용한 경우 Controller class의 이름이 url로 자동 매핑된다.
<bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/> <bean class="blog.web.FindBlogController"> <property name="blogService" ref="blogService"/> </bean>
- 한계
- ControllerClassNameHandlerMapping을 사용하더라도, 각 controller 파일에 대해 bean 등록을 직접 해주어야 한다.
- 클래스 및 메소드의 이름이 url로 사용되므로, 클래스 및 메소드 이름 결정에 주의해야 한다.
- Controller의 종류에 따라 url 매핑의 형태가 다르므로, jsp 소스 코드 관리에 주의해야 한다.
- MultiActionController의 경우 /클래스이름/메소드이름.확장자로 매핑되며, 다른 Controller의 경우 /클래스이름.확장자로 매핑된다.
[편집] Arid + ControllerClassNameHandlerMapping
- Arid의 자동 bean 등록과 ControllerClassNameHandlerMapping의 url 자동 매핑의 기능을 사용하여 설정파일을 간략하게 사용할 수 있다.
- Web Controller는 MultiActionController를 상속받아 사용함으로써 Controller 클래스의 수를 줄일 수 있다.
[편집] servlet 설정
- Arid와 ControllerClassNameHandlerMapping의 설정 만으로 기존의 url-controller class 설정을 모두 생략할 수 있다.
- InternalResourceViewResolver는 Controller에서 ModelAndView 타입이 아닌 ModelMap 타입으로 반환하더라도 알맞은 View를 선택하여 보여주도록 해준다.
- stripLeadingSlash 속성은 false로 설정을 해야 requestContext 이후의 정확한 url 매핑이 이루어진다. (stripLeadingSlash의 default value는 true이다.)
- InternalResourceViewResolver를 사용할 경우 suffix를 지정하기 위해 사용한 InternalResourceViewResolver를 중복으로 사용하지 않아도 된다. (단, 특정 viewClass를 지정하거나 InternalResourceViewResolver에서 필요한 속성을 설정하기 위해서는 지정해준다.)
<!-- blog-servlet.xml --> <?xml version="1.0" encoding="UTF-8" ?> <beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:jee="http://www.springframework.org/schema/jee" xmlns:tx="http://www.springframework.org/schema/tx" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p" xmlns:arid="http://chrisrichardson.net/schema/arid" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd http://www.springframework.org/schema/jee http://www.springframework.org/schema/jee/spring-jee-2.0.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-2.5.xsd http://chrisrichardson.net/schema/arid http://chrisrichardson.net/schema/arid.xsd" > <!-- auto registration and wiring of beans --> <arid:define-beans package="edu.blog" pattern="*..web.*Controller" autowire="byName"/> <bean class="org.springframework.web.servlet.mvc.support.ControllerClassNameHandlerMapping"/> <bean id="viewNameTranslator" class="org.springframework.web.servlet.view.DefaultRequestToViewNameTranslator"> <property name="stripLeadingSlash" value="false"/> <property name="suffix" value=".jsp"/> </bean> <!-- view & resolver <bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver"> <property name="suffix" value=".jsp"/> <property name="viewClass" value="org.springframework.web.servlet.view.JstlView"/> </bean> --> </beans>
[편집] Web Controller
- 하나의 controller에서 처리하기 위해 MultiActionController를 사용하고, 메소드 형태의 혼란을 줄이기 위해 같은 형태의 메소드를 사용하였다.
- 다른 레이어와 연계가 필요한 멤버변수(blogService)는 setXxx 함수로 설정을 해준다.
- 서블릿에서 InternalResourceViewResolver를 사용하지 않을 경우, 반환형을 ModelAndView로 하여 view 이름을 지정해주어야 한다.
- deleteBlog()와 같이 직접 view로 반환하지 않는 메소드는 return type이 Map/ModelAndView형태가 아니어도 된다.
- redirect/forword 키워드로 알맞은 url로 변환해준다.
/* BlogController.java */ /* 패키지 선언 및 import 생략 */ public class BlogController extends MultiActionController { private BlogService blogService; public void setBlogService(BlogService blogService) { this.blogService = blogService; } public Map findBlogs(HttpServletRequest request, HttpServletResponse response) throws Exception { Collection blogList = blogService.findBlogs(); return new ModelMap("blogList", blogList); } public String deleteBlog(HttpServletRequest request, HttpServletResponse response) throws Exception { blogService.deleteBlog(Integer.parseInt((String)request.getParameter("blogId"))); return "redirect:findBlogs.do"; }
- get 형태의 파라미터는 request.getParameter()로, post 형태의 form 관련 파라미터는 bind() 함수로 설정할 수 있다.
- SessionAttributes Annotation과 같이 하나의 blog 모델을 유지할 수 없기 때문에, View에서는 Controller에서 넘겨준 모델의 모든 정보를 다시 설정하여 보내주도록 해야한다. (blog 예제 소스 참고)
public Map createBlog(HttpServletRequest request, HttpServletResponse response) throws Exception { Blog blog = new Blog(); blog.setRegDate(new Date()); return new ModelMap("blog", blog); } public String addBlog(HttpServletRequest request, HttpServletResponse response) throws Exception { Blog blog = new Blog(); bind(request, blog); blogService.createBlog(blog); return "redirect:findBlogs.do"; } /* 중간 생략 */
- MultiActionController로부터 override한 initBinder 함수는 form 관련 속성 값들에 대한 설정이 필요할 때 사용한다.
- 이 예제에서는 Date Type과 String Type의 변환을 위해 initBind() 메소드를 사용하였다.
// Override protected void initBinder(HttpServletRequest request, ServletRequestDataBinder binder) throws Exception { DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); CustomDateEditor dateEdit = new CustomDateEditor(df, false); binder.registerCustomEditor(Date.class, dateEdit); } }
[편집] Spring MVC Blog 예제 다운로드
- SpringMVC + springframework + iBatis으로 이루어진 예제이다.
- Spring MVC Blog 예제 다운로드
- 데이터베이스는 Oracle을 사용하였다.
|
