2017년 6월 22일 목요일

spring 다국어 설정

1. context-common.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:jdbc="http://www.springframework.org/schema/jdbc"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/jdbc  http://www.springframework.org/schema/jdbc/spring-jdbc-4.0.xsd">
 <!-- CookieLocaleResolver : 쿠키를 이용한 locale정보 사용 
      SessionLocaleResolver : 세션을 이용한 locale정보 사용 
      AcceptHeaderLocaleResolver : 클라이언트의 브라우져에 설정된 locale정보 사용 
       Bean 설정 파일에 정의하지 않을 경우 AcceptHeaderLocaleResolver 를 default 로 적용된다. -->
 <bean id="localeResolver" class="org.springframework.web.servlet.i18n.SessionLocaleResolver" />
 <!-- 사용자의 브라우져의 Locale 정보를 이용하지 않고 사용자가 선택하여 언어를 직접 선택할 수 있도록 구현하려 한다면 
      CookieLocaleResolver 나 SessionLocaleResolver 를 이용한다.
                     먼저 다국어를 지원해야 하므로 메세지를 MessageSource 로 추출하여 구현해야 한다. -->
 <bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource">
  <property name="basenames">
   <list>
    <value>classpath:/egovframework/message/message-common</value> <!-- 파일경로 -->
   </list>
  </property>
  <property name="cacheSeconds">
   <value>60</value>
  </property>
 </bean>
    
</beans>

2. dispatcher-servlet.xml 수정

<mvc:interceptors>  
 <mvc:interceptor>
  <mvc:mapping path="/**" />
  <bean class="org.springframework.web.servlet.i18n.LocaleChangeInterceptor">
   <property name="paramName" value="lang" />
  </bean>
 </mvc:interceptor>
</mvc:interceptors>

3. Web 을 통해 들어오는 요청을 Charset UTF-8 적용한다. CharacterEncodingFilter 을 이용하여 encoding 할 수 이도록 아래와 같이 세팅한다


<?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>dev</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>/*</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/springmvc/dispatcher-servlet.xml</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>

4. properties 파일 추가 


각 파일에 key value 값으로 작성한다
ex) button.search=Search

5. jsp에서 spring태그를 이용해서 사용한다.


<%@ taglib prefix="spring" uri="http://www.springframework.org/tags"%>
<spring:message code="board.subject"/>

6. 다국어 설정 되었는지 테스트 

ex) http://localhost:8080/list.do?lang=ko / http://localhost:8080/list.do?lang=en
Share:

spring log4j2 설정

1. pom.xml 추가

<dependency>
 <groupId>org.bgee.log4jdbc-log4j2</groupId>
 <artifactId>log4jdbc-log4j2-jdbc4.1</artifactId>
 <version>1.16</version>
</dependency>

2. dataSource 수정


<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
    <property name="driverClassName" value="net.sf.log4jdbc.sql.jdbcapi.DriverSpy"/>
    <property name="url" value="jdbc:log4jdbc:mysql:thin:@123.456.789.12:1521:test" />
    <property name="username" value="test"/>
    <property name="password" value="123"/>
</bean>

3. log4j2.xml 수정


<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
    <Appenders>
        <!-- Console 출력을 위한 Appender -->
        <Console name="console" target="SYSTEM_OUT">
            <PatternLayout pattern="%d %5p [%c] %m%n" />
        </Console>
    </Appenders>
    <Loggers>
        <Logger name="java.sql" level="INFO" additivity="false">
            <AppenderRef ref="console" />
            <AppenderRef ref="dailyRollingFileAppender" />
        </Logger>
        <Logger name="egovframework" level="DEBUG" additivity="false">
            <AppenderRef ref="console" />
            <AppenderRef ref="dailyRollingFileAppender" />
        </Logger>
  <!-- log SQL with timing information, post execution -->
        <Logger name="jdbc.sqltiming" level="INFO" additivity="false">
            <AppenderRef ref="console" />
            <AppenderRef ref="dailyRollingFileAppender" />
        </Logger>
        <Logger name="org.springframework" level="INFO" additivity="false">
            <AppenderRef ref="console" />
            <AppenderRef ref="dailyRollingFileAppender" />
        </Logger>
        <Root level="INFO">
            <AppenderRef ref="console" />
            <AppenderRef ref="dailyRollingFileAppender" />
        </Root>
    </Loggers>
</Configuration>
Share:

2017년 6월 20일 화요일

2017년 6월 16일 금요일

context:component-scan vs context:annotation-config vs mvc:annotation-driven

1. context:component-scan

@Component 
@Repository 
@Service 
@Controller 
을 bean으로 등록하고
@Autowired 
@Qualifier
을 인식한다.

2. context:annotation-config

<!--RequiredAnnotationBeanPostProcessor @Required 사용시
         AutowiredAnnotationBeanPostProcessor @Autowired 사용시
         CommonAnnotationBeanPostProcessor @Resource, @PoastConstruct, @PreDestroy 사용시
         ConfigurationClassPostProcessor @Configuration 사용시  
         context를 명시하면 context태그 하나로 사용가능  
        <context:annotation-config/> -->

(context:component-scan 을 정의한 경우 Annotation 인식을 위한 설정 context:annotation-config 을 별도로 추가하지 않아도 됩니다.)

3. mvc:annotation-driven

- DefaultAnnotationHandlerMapping


가장 우선으로 적용되도록 @RequestMapping 을 이용한 핸들러 매핑 전략을 등록한다. 따라서 다른 디폴트 핸들러 매핑 전략은 자동 등록되지 않는다는 점을 기억해두자.


- AnnotationMethodHandlerAdapter


AnnotationMethodHandlerAdapter 는 DispatcherServlet 이 자동으로 등록해주는 디폴트 핸들러 어댑터다. 하지만 디폴트 설정을 변경하려면 빈으로 등록해야 한다. <mvc:annotation-driven> 은 기본적으로 이 AnnotationMethodHandlerAdapter 를 빈으로 등록한다. 따라서 <mvc:annotation-driven> 을 사용했을 때는 직접 AnnotationMethodHandlerAdapter 빈을 등록해서는 안된다. 또, 핸들러 어댑터 전략을 빈으로 등록했으므로 그 밖의 디폴트 핸들러 어댑터 전략은 자동등록되지 않는다.

- ConfigurableWebBindingInitializer


모든 컨트롤러 메소드에 자동으로 적용되는 WebDataBinder 초기화용 빈을 등록하고 AnnotationMethodHandlerAdapter 의 프로퍼티로 연결해 준다.

기본적으로 컨버전 서비스는 @NumberFormat 과 같은 애노테이션 방식의 포맷터를 지원하는 FormattingConversionServiceFactoryBean 이 등록된다.

글로벌 검증기는 LocalValidatorFactoryBean 으로 설정된다. 따라서 JSR-303 의 검증용 애노테이션 기능이 자동으로 제공된다. 단, 이 기능이 적용되려면 JSR-303 지원 라이브러리가 클래스패스에 등록되어 있어야 한다. JSR-303 라이브러리가 없다면 LocalValidatorFactoryBean 은 등록되지 않는다.

- 메시지 컨버터


AnnotationMethodHandlerAdapter 의 messageConverters 프로퍼티로 메시지 컨버터들이 등록된다. 네 개의 디폴트 메시지 컨버터와 함께 Jaxb2RootElementHttpMessageConverter 와 MappingJacksonHttpMessageConverter 가 추가로 등록된다. 단, 각각 JAXB2 와 Jackson 라이브러리가 클래스 패스에 존재하는 경우에만 등록된다.

- <spring:eval> 을 위한 컨버전 서비스 노출용 인터셉터


<spring:eval> 은 기본적으로 표준 컨버터를 이용해서 모델의 프로퍼티 값을 JSP 에 출력할 문자열로 변환한다. 하지만 <mvc:annotation-driven> 을 등록해 주면 <spring:eval> 에서 컨버전 서비스를 이용할 수 있다. ConfigurableWebBindingInitializer 에 등록되는 것과 동일한 컨버전 서비스를 인터셉터를 이용해서 <spring:eval> 태그에서 사용할 수 있도록 제공해주는 기능이 자동으로 추가된다. 이 덕분에 폼에 모델 정보를 출력할 때와 마찬가지로 스프링 컨버터나 포맷터의 강력한 오브젝트-스트링 타입변환 기능이 <spring:eval> 에 적용된다.

<mvc:annotation-driven> 이 자동으로 등록해주는 몇 가지 설정정보는 애트리뷰트를 이용해 바꿀 수 있다. 직접 만든 커스텀 검증기, 컨버전 서비스 등을 적용할 때는 다음과 같은 애트리뷰트를 사용해 등록해주면 된다.


- validator


자동 등록되는 ConfigurableWebBindingInitializer 의 validator 프로퍼티에 적용할 Validator 타입의 빈을 지정할 수 있다. 모든 컨테이너에 일괄 적용하는 검증기는 디폴트로 추가되는 JSR-303 방식의 LocalValidatorFactoryBean 이면 충분하다. 모델 단위의 검증기는 컨트롤러 레벨에서 직접 DI 받아서 사용하는 편이 낫기 때문이다. 하지만 LocalValidatorFactoryBean 을 확장하거나 재구성하려면 직접 빈으로 등록해줄 필요가 있다. 이때 validator 애트리뷰트를 이용해 다음과 같이 등록해 줘야 한다.

- conversion-service


ConfigurableWebBindingInitializer 의 conversionService 프로퍼티에 설정될 빈을 직접 지정할 수 있다. 스프링이 제공하는 컨버전 서비스만 사용한다면 디폴트로 등록되는 FormattingConversionServiceFactoryBean 으로 충분하겠지만, 직접 개발한 컨버터나 포맷터를 적용하려면 FormattingConversionServiceFactoryBean 을 빈으로 직접 등록하고 재구성해줘야 한다. 이때는 conversion-service 애트리뷰트를 이용해 다음과 같이 설정해주면 된다.


<mvc:annotation-driven> 은 매우 빠르고 간편하게 @MVC 의 주요 빈을 설정하고 최신 기능을 사용하게 해준다. 하지만 검증기와 컨버전 서비스를 제외하면 기본적으로 등록되는 빈의 설정을 변경할 수 없다. AnnotationMethodHandlerAdapter 와 DefaultAnnotationHandlerMapping 등의 설정을 변경해야할 때는 <mvc:annotation-driven> 을 사용할 수 없다. 이때는 직접 필요한 빈을 등록하고 프로퍼티를 통해 설정해줘야 한다.

*출처 : http://springsource.tistory.com/90

Share: