본문 바로가기

프로그래밍/Spring

전자정부 프레임워크를 Java Config 방식으로 설정해보자(dispatcher-servlet.xml 변환) - 3

지난 글에서는 Java Config 방식으로 Spring MVC 환경 설정하는 방법 중 HandlerExceptionResolver를 등록하는 방법과 view-controller 설정 방법에 대해. 이번에는 이렇게 만들어진 Java Config 방식의 클래스를 어떻게 사용하는지에 대해 설명하도록 하겠다.

 

예전에 RootContext 클래스에 대해 설명했던 것을 떠올려보도록 하자. RootContext 클래스는 Spring Root Context 관련 환경 설정의 Java Config 클래스를 Import 하고 이러한 RootContext 클래스를 web.xml에 설정함으로써 WAS에 Sample 프로젝트가 올라갈때 이 RootContext 클래스를 이용해서 Spring의 Root Context 환경을 구성하도록 했다. Sample 프로젝트의 Servlet Context 환경 설정은 dispatcher-servlet.xml 이 파일 하나뿐이 없기 때문에 이와 매핑되는 ServletContext 클래스 하나만 만들어서 여기에 모두 구성했다. ServletContext 클래스 또한 어딘가에 설정을 해 둬야 WAS에 Sample 프로젝트가 올라갈때 이 클래스를 이용해서 Servlet Context를 구성할 것이 아닌가? 이 작업 또한 RootContext 클래스와 마찬가지로 web.xml에 설정하도록 한다.

 

기존의 web.xml에서 Servlet Context를 로딩하는 부분은 다음과 같이 되어 있다

 

<servlet>
	<servlet-name>action</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<init-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>/WEB-INF/config/egovframework/springmvc/dispatcher-servlet.xml</param-value>
	</init-param>
	<load-on-startup>1</load-on-startup>
</servlet>

 

이 XML 내용을 보면 dispatcher-servlet.xml을 읽어서 Servlet Context를 구성하는 것을 알 수 있다. 이 부분을 이제 Java Config 방식으로 만든 ServletContext 클래스를 이용해서 Servlet Context를 구성하게끔 해주면 된다. 다음과 같이 말이다. 

 

<servlet>
	<servlet-name>action</servlet-name>
	<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
	<init-param>
		<param-name>contextClass</param-name>
		<param-value>
			org.springframework.web.context.support.AnnotationConfigWebApplicationContext
		</param-value>
	</init-param>
	<init-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>egovframework.example.config.servlet.ServletContext</param-value>
	</init-param>
	<load-on-startup>1</load-on-startup>
</servlet>

 

예전에 Root Context를 로딩하기 위해 web.xml을 설정하는 부분에 대한 내용과 비슷한 구조이다. contextClass 파라미터에 AnnotatonConfigWebApplicationContext 클래스를 지정하고 contextConfigLocation 파라미터에 ServletContext 클래스를 지정했다. 이런 설정으로 web.xml에서 Servlet Context를 로딩하게 된다.

 

지금까지 3개의 글에 걸쳐서 설명한 dispatcher-servlet.xml 설정파일을 Java Config 방식으로 변경한 ServletContext 클래스 소스와 이 ServletContext 클래스 소스를 이용해서 Servlet Context를 로딩하는 web.xml에 대한 소스를 올리도록 하겠다. web.xml 소스를 보면 앞에서 설명했던 Root Context을 올리는 부분도 같이 포함되어 있다.

 

package egovframework.example.config.servlet;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Properties;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.FilterType;
import org.springframework.stereotype.Controller;
import org.springframework.stereotype.Repository;
import org.springframework.stereotype.Service;
import org.springframework.web.servlet.HandlerExceptionResolver;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurationSupport;
import org.springframework.web.servlet.handler.SimpleMappingExceptionResolver;
import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;
import org.springframework.web.servlet.i18n.SessionLocaleResolver;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter;
import org.springframework.web.servlet.view.JstlView;
import org.springframework.web.servlet.view.UrlBasedViewResolver;

import egovframework.example.cmmn.web.EgovBindingInitializer;
import egovframework.example.cmmn.web.EgovImgPaginationRenderer;
import egovframework.rte.ptl.mvc.tags.ui.pagination.DefaultPaginationManager;
import egovframework.rte.ptl.mvc.tags.ui.pagination.PaginationRenderer;

@Configuration
@ComponentScan(
		basePackages="egovframework",
		includeFilters={
			@ComponentScan.Filter(type=FilterType.ANNOTATION, value=Controller.class)	
		},
		excludeFilters={
			@ComponentScan.Filter(type=FilterType.ANNOTATION, value=Service.class)
			, @ComponentScan.Filter(type=FilterType.ANNOTATION, value=Repository.class)
			, @ComponentScan.Filter(type=FilterType.ANNOTATION, value=Configuration.class)
		}
)
public class ServletContext extends WebMvcConfigurationSupport {
	
	@Bean
	@Override
	public RequestMappingHandlerAdapter requestMappingHandlerAdapter() {
		// TODO Auto-generated method stub
		RequestMappingHandlerAdapter rmha = super.requestMappingHandlerAdapter();
		rmha.setWebBindingInitializer(new EgovBindingInitializer());
		return rmha;
	}

	@Override
	protected void addInterceptors(InterceptorRegistry registry) {
		registry.addInterceptor(localeChangeInterceptor());
	}

	@Bean
	public SessionLocaleResolver localeResolver(){
		SessionLocaleResolver sessionLocaleResolver = new SessionLocaleResolver();
		return sessionLocaleResolver;
	}
	
	/*
	// 쿠키를 이용한 Locale 이용시 이 부분을 주석처리를 풀어서 사용하고 위에 있는 SessionLocaleResolver 클래스를 사용하는
	// @Bean 메소드는 주석처리 한다
	@Bean
	public CookieLocaleResolver localeResolver(){
		CookieLocaleResolver cookieLocaleResolver = new CookieLocaleResolver();
		return cookieLocaleResolver;
	} 
	 */
    
    @Bean
    public LocaleChangeInterceptor localeChangeInterceptor(){
    	LocaleChangeInterceptor localeChangeInterceptor = new LocaleChangeInterceptor();
    	localeChangeInterceptor.setParamName("language");
    	return localeChangeInterceptor;
    }
    
    
    /**
     * WebMvcConfigurationSupport 클래스의 handlerExceptionResolver 메소드(@Bean 어노테이션이 선언되어 있기 때문에
     * Spring Bean을 등록하는 메소드이다)에서 파라미터로 넘긴 exceptionResolvers에 들어있는
     * ExceptionResolver들을 모두 관리하는 HandlerExceptionResolverComposite 클래스를 Spring Bean으로 등록한다
     * 그렇기땜에 특정 exceptionResolvers에 자신이 사용하고자 하는 ExceptionResolver들을 넣으면 된다
     * 만약 이 작업을 하지 않으면 WebMvcConfigurationSupport 클래스의 handlerExceptionResolver 메소드는
     * ExceptionHandlerExceptionResolver 클래스 객체와 ResponseStatusExceptionResolver 클래스 객체만을 
     * ExceptionResolver로 사용한다
     */
    @Override
	protected void configureHandlerExceptionResolvers(List<HandlerExceptionResolver> exceptionResolvers) {
		// TODO Auto-generated method stub
    	SimpleMappingExceptionResolver smer = new SimpleMappingExceptionResolver();
    	smer.setDefaultErrorView("cmmn/egovError");
    	Properties mappings = new Properties();
    	mappings.setProperty("org.springframework.dao.DataAccessException", "cmmn/dataAccessFailure");
    	mappings.setProperty("org.springframework.transaction.TransactionException", "cmmn/transactionFailure");
    	mappings.setProperty("egovframework.rte.fdl.cmmn.exception.EgovBizException", "cmmn/egovError");
    	mappings.setProperty("org.springframework.security.AccessDeniedException", "cmmn/egovError");
    	smer.setExceptionMappings(mappings);
    	exceptionResolvers.add(smer);
	}
    
    @Bean
    public UrlBasedViewResolver urlBasedViewResolver(){
    	UrlBasedViewResolver urlBasedViewResolver = new UrlBasedViewResolver();
    	urlBasedViewResolver.setOrder(1);
    	urlBasedViewResolver.setViewClass(JstlView.class);
    	urlBasedViewResolver.setPrefix("/WEB-INF/jsp/egovframework/example/");
    	urlBasedViewResolver.setSuffix(".jsp");
    	return urlBasedViewResolver;
    }

    @Bean
    public EgovImgPaginationRenderer imageRenderer(){
    	EgovImgPaginationRenderer egovImgPaginationRenderer = new EgovImgPaginationRenderer();
    	return egovImgPaginationRenderer;
    }
    
    @Bean
    public DefaultPaginationManager paginationManager(EgovImgPaginationRenderer imageRenderer){
    	DefaultPaginationManager defaultPaginationManager = new DefaultPaginationManager();
    	Map<String, PaginationRenderer> rendererType = new HashMap<String, PaginationRenderer>();
    	rendererType.put("image", imageRenderer);
    	defaultPaginationManager.setRendererType(rendererType);
    	return defaultPaginationManager;
    }
	
    @Override
	protected void addViewControllers(ViewControllerRegistry registry) {
		// TODO Auto-generated method stub
		registry.addViewController("/cmmn/validator.do").setViewName("cmmn/validator");
	}

}

 

<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xmlns="http://java.sun.com/xml/ns/javaee" xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
	id="WebApp_ID" version="2.5">
	<display-name>egov.sample</display-name>
    
	<filter>
		<filter-name>encodingFilter</filter-name>
		<filter-class>org.springframework.web.filter.CharacterEncodingFilter</filter-class>
		<init-param>
			<param-name>encoding</param-name>
			<param-value>utf-8</param-value>
		</init-param>
	</filter>
	<filter-mapping>
		<filter-name>encodingFilter</filter-name>
		<url-pattern>*.do</url-pattern>
	</filter-mapping>
    
	<filter>
		<filter-name>HTMLTagFilter</filter-name>
		<filter-class>egovframework.rte.ptl.mvc.filter.HTMLTagFilter</filter-class>
	</filter>
	<filter-mapping>
		<filter-name>HTMLTagFilter</filter-name>
		<url-pattern>*.do</url-pattern>
	</filter-mapping>
    
    <!-- 
	<context-param>
		<param-name>contextConfigLocation</param-name>
		<param-value>classpath*:egovframework/spring/context-*.xml</param-value>
	</context-param>
    
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
    
	<servlet>
		<servlet-name>action</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
		<init-param>
			<param-name>contextConfigLocation</param-name>
			<param-value>/WEB-INF/config/egovframework/springmvc/dispatcher-servlet.xml</param-value>
		</init-param>
		<load-on-startup>1</load-on-startup>
	</servlet>
    -->
    <context-param>
   		<param-name>contextClass</param-name>
      	<param-value>
        	org.springframework.web.context.support.AnnotationConfigWebApplicationContext
      	</param-value>
  	</context-param>
    
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>egovframework.example.config.root.RootContext</param-value>
    </context-param>
    
	<listener>
		<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
	</listener>
	
	<servlet>
		<servlet-name>action</servlet-name>
		<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextClass</param-name>
            <param-value>
            	org.springframework.web.context.support.AnnotationConfigWebApplicationContext
            </param-value>
        </init-param>
        <init-param>
        	<param-name>contextConfigLocation</param-name>
          	<param-value>egovframework.example.config.servlet.ServletContext</param-value>
      	</init-param>
        <load-on-startup>1</load-on-startup>
	</servlet>
	
	<servlet-mapping>
		<servlet-name>action</servlet-name>
		<url-pattern>*.do</url-pattern>
	</servlet-mapping>
    
	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>
    
	<login-config>
		<auth-method>BASIC</auth-method>
	</login-config>
    
	<error-page>
		<exception-type>java.lang.Throwable</exception-type>
		<location>/common/error.jsp</location>
	</error-page>
	<error-page>
		<error-code>404</error-code>
		<location>/common/error.jsp</location>
	</error-page>
	<error-page>
		<error-code>500</error-code>
		<location>/common/error.jsp</location>
	</error-page>
    
</web-app>

 

이상으로 전체적인 Java Config 방식으로의 설정에 대한 설명이 모두 끝이 났다. 지금까지의 내용을 잘 읽은 사람이라면 Java Config 방식으로의 설정이 어렵게 느껴지지 않을 것이다. 자신이 했던 프로젝트, 또는 앞으로 자신이 진행할 프로젝트의 환경설정을 Java Config 방식으로 바꾸어서 진행해보라. 개발의 편리함이 한층 올라갈 것이다. 스터디 하는 방법을 추천하자면 전자정부 프레임워크 개발툴에서 Sample 프로젝트를 프로젝트 이름만 달리해서 2개를 만든 다음에 하나는 가만 내비두고 남은 다른 하나를 이용해서 지금까지 연재한 글을 보며 환경설정을 바꾸는 방법으로 진행하면 도움이 될 것이다. 또한 Spring Framework Javadoc API 문서를 같이 보면 더욱 좋다. 

 

 

 1. 전자정부 프레임워크를 Java Config 방식으로 설정해보자(환경구축)

 2. 전자정부 프레임워크를 Java Config 방식으로 설정해보자(기초)

 3. 전자정부 프레임워크를 Java Config 방식으로 설정해보자(context-aspect.xml 변환)

 4. 전자정부 프레임워크를 Java Config 방식으로 설정해보자(context-common.xml 변환)

 5. 전자정부 프레임워크를 Java Config 방식으로 설정해보자(context-datasource.xml 변환)

 6. 전자정부 프레임워크를 Java Config 방식으로 설정해보자(context-sqlMap.xml, context-mapper.xml 변환)

 7. 전자정부 프레임워크를 Java Config 방식으로 설정해보자(context-transaction.xml 변환)

 8. 전자정부 프레임워크를 Java Config 방식으로 설정해보자(context-idgen.xml, context-properties.xml, context-validator.xml 변환)

 9. 작성된 Java Config 클래스 파일들을 실제 등록해보자(RootContext 클래스 제작)

 10. 전자정부 프레임워크를 Java Config 방식으로 설정해보자(dispatcher-servlet.xml 변환) - 1

 11. 전자정부 프레임워크를 Java Config 방식으로 설정해보자(dispatcher-servlet.xml 변환) - 2

 12. 전자정부 프레임워크를 Java Config 방식으로 설정해보자(dispatcher-servlet.xml 변환) - 3