목차 >> Web 화면 개발 
+- Spring Web MVC  
----+- HandlerMapping  
--------+- Interceptor  
----+- ViewResolver  
+- GlueAbstractController  
----+- GlueSimpleController  
----+- GlueJsonController

12장 Web 화면 개발

Glue Framework에서는 Web 화면 개발은 기본적으로 Spring Web MVC framework을 바탕으로 합니다.

DispatcherServlet

Spring Web MVC framework 은 request를 handler에게 전달하는 DispatcherServlet을 중심으로 설계되었습니다.
DispatcherServlet은 HttpServlet을 상속한 클래스 이므로 web.xml에 선언되어야 합니다. DispatcherServlet이 초기화되면, WEB-INF 디렉토리에서 [servlet-name]-servlet.xml 파일을 찾습니다.

다음과 같이 web.xml에 DispatcherServlet이 정의 되어 있다면, 파일명이 dispatcher-servlet.xml 인 파일이 필요합니다. (DispatcherServlet 의 'init-param' 을 통해 파일이름 변경 가능함)

<servlet>
    <servlet-name>dispatcher</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>dispatcher</servlet-name>
    <url-pattern>*.do</url-pattern>
</servlet-mapping>

DispatcherServlet은 [servlet-name]-servlet.xml에 근거해 자신만의 WebApplicationContext을 갖게 됩니다. [servlet-name]-servlet.xml 에는 controller, view resolver, locale resolver 등의 bean이 선언되어 있습니다.

<bean id="handlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <value>
            /*.mvc=controller
        </value>
    </property>
</bean>
<bean name="controller" class="com.poscoict.glueframework.web.control.spring.GlueSimpleController" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
  <property name="prefix" value="/springmvc/" />
  <property name="suffix" value=".jsp" />
</bean>

HandlerMapping

HandlerMapping 은 WebApplicationContext의 정의된 특별한 bean 중의 하나로 다음 클래스를 사용할 수 있습니다.

  • org.springframework.web.servlet.handler.SimpleUrlHandlerMapping
    <bean id="handlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
        <property name="mappings">
            <value>
                /content/*.mvc=controller
                /**/help.mvc=helpController
            </value>
        </property>
    </bean>
    <bean name="controller" class="com.poscoict.glueframework.web.control.spring.GlueSimpleController" />
    <bean name="helpController" class=". . ." />
    
  • org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping
    <bean id="handlerMapping" class="org.springframework.web.servlet.handler.BeanNameUrlHandlerMapping"/>
    <bean name="/hello.mvc" class="com.poscoict.glueframework.web.control.spring.GlueSimpleController" />
    <bean name="/help.mvc" class=". . ." />
    

    그외 HandlerMapping 관련 클래스는 spring documentation 을 참고하도록 합니다.

Interceptor

Spring의 HandlerMapping 매커니즘에는 Interceptor를 포함합니다. 아래 예제와 같이 handlerMapping bean에 interceptor를 포함시키는 것입니다.

<bean id="handlerMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="interceptors">
        <list>
           <ref bean="sessionChecker"/>
        </list>
    </property>
    <property name="mappings">
        <props>
            /*.mvc=controller
        </props>
    </property>
</bean>
<bean id="sessionChecker" class="sample.CheckSessionInterceptor"/>
<bean id="controller" class=". . ."/>

Interceptor는 org.springframework.web.servlet 패키지의 HanderIntercepor 인터페이스를 구현해야 합니다. 해당 인터페이스에는 3개의 메소드가 정의되어 있으며, 다음과 같습니다.

  • boolean preHandle(HttpServletRequest req, HttpServletResponse res, Object obj)
  • void postHandle(HttpServletRequest req, HttpServletResponse res, Object res, ModelAndView mv)
  • void afterCompletion(HttpServletRequest req, HttpServletResponse res, Object res, Exception e)

    예제의 sessionChecker 가 사용자정보 유무에 따라 request를 처리할지 판단한다면, 다음과 같이 구현할 수 있습니다. 예제에 사용된 HandlerInterceptorAdapter은 HanderIntercepor를 구현한 추상 클래스 입니다.

    package sample;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
    
    public class CheckSessionInterceptor extends HandlerInterceptorAdapter
    {
    
        @Override
        public boolean preHandle( HttpServletRequest request, HttpServletResponse response, Object handler ) throws Exception
        {
            if(request.getSession().getAttribute("userId") != null)
            {
                return true;
            } else {
                response.sendRedirect("login.jsp");
                return false;
            }
        }
    }
    

ViewResolver

ViewResolver 도 WebApplicationContext의 정의된 특별한 bean 중의 하나로 다음 클래스를 사용할 수 있습니다.

  • org.springframework.web.servlet.view.InternalResourceViewResolver
  • org.springframework.web.servlet.view.XmlViewResolver

    그외 ViewResolver 관련 클래스는 spring documentation 을 참고하도록 합니다.

GlueAbstractController

Spring Web MVC framework 에서는 Controller를 통해 application 동작에 대한 액세스를 제공합니다. 그래서 Glue Framework에서는 Controller를 통해 GlueService를 실행하는 할 수 있도록 추상클래스인 GlueAbstractController가 있습니다. GlueAbstractController 에서 제공하는 메소드는 Java Doc을 참고합니다. (GlueAPI)

그림 : GlueAbstractController
GlueAbstractController

GlueAbstractController는 GlueService 실행을 위한 기본 로직이 구현되어 있는 추상 Class로써, 다음 3개 메소드를 구현해야 합니다.

  • abstract void preDoAction(GlueWebContext ctx) : 서비스 실행 전 실행되는 메서드
  • abstract void afterDoAction(GlueWebContext ctx) : 서비스 실행 후 실행되는 메서드
  • abstract ModelAndView setModelAndView(GlueWebContext ctx) : return할 ModelAndView 생성

GlueSimpleController

GlueSimpleController는 GlueAbstractController을 상속받아서 구현된 Controller 입니다. GlueService 실행 전후 특별히 추가해야 할 로직이 없다면 GlueSimpleController를 사용하면 됩니다. GlueService 실행 후 view page가 설정되어 있지 않으면 Url을 기초로 view page를 설정합니다.
아래와 같이 controller가 매핑되어 있다면, url이 dept.mvc 의 경우의 view page는 dept로 설정됩니다. 그리고 viewResolver에 따라 /jsp 위치의 dept.jsp 파일이 최종 view가 됩니다.

<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <value>
            /*.mvc=controller
        </value>
    </property>
</bean>
<bean id="controller" class="com.poscoict.glueframework.web.control.spring.GlueSimpleController" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.InternalResourceViewResolver">
    <property name="prefix" value="/jsp/" />
    <property name="suffix" value=".jsp" />
</bean>

에러가 발생될 경우의 view page를 변경하고 싶다면 errorPage property를 설정하면 됩니다. 에러가 발생하지 않을 경우의 view page를 url과 관계없이 설정하고자 할 경우에는 viewPage property를 이용할 수 있습니다. 다음은 GlueSimpleController 의 property를 설정한 예입니다.

<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <value>
            /biz.mvc=controller
        </value>
    </property>
</bean>
<bean name="controller" class="com.poscoict.glueframework.web.control.spring.GlueSimpleController">
    <property name="viewPage" value="view" />
    <property name="errorPage" value="error" />
</bean>

제공되는 예제 'sample-hello-springmvc' 에서 dispatcher-servlet.xml 을 통해 응용해 보시기 바랍니다.

GlueJsonController

GlueJsonController는 GlueAbstractController을 상속받아서 구현된 Controller 입니다. GlueService 실행 전후 특별히 추가해야 할 로직이 없다면 GlueJsonController를 사용하면 됩니다. GlueService 실행 결과는 json data가 되며, GlueJsonController의 기본 view page는 jsonView 입니다.

<bean id="urlMapping" class="org.springframework.web.servlet.handler.SimpleUrlHandlerMapping">
    <property name="mappings">
        <value>
            /*.json=controller
        </value>
    </property>
</bean>
<bean id="controller" class="com.poscoict.glueframework.web.control.spring.GlueJsonController" />
<bean id="viewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
<bean name="jsonView" class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"/>

GlueJsonController의 기본 view page는 다음과 같이 변경할 수 있습니다.

<bean name="controller" class="com.poscoict.glueframework.web.control.spring.GlueSimpleController">
    <property name="viewPage" value="view" />
</bean>
<bean id="viewResolver" class="org.springframework.web.servlet.view.BeanNameViewResolver"/>
<bean name="view" class="org.springframework.web.servlet.view.json.MappingJacksonJsonView"/>

GlueJsonController는 GlueService 실행 후 GlueContext에 담긴 data의 일부를 json으로 변환합니다. json 변환이 되는 대상은 GlueResultKeyList activity를 통해 지정합니다.

<?xml version="1.0" encoding="UTF-8"?>
<service name="hello-json-service" initial="HelloActivity" xmlns="http://www.poscoict.com/glueframework/service">
    <activity name="HelloActivity" class="sample.activity.SampleData">
        <transition name="success" value="ResultKey List"/>
    </activity>
    <activity name="ResultKey List" class="com.poscoict.glueframework.biz.activity.GlueResultKeyList">
        <transition name="success" value="end"/>
        <property name="ctx-keys" value="flower|fruits|vegatable"/>
    </activity>
</service>

제공되는 예제 'sample-hello-springmvc' 에서 dispatcher-json-servlet.xml 을 통해 응용해 보시기 바랍니다.