📕🐘 도로락 - 코끼리를 냉장고에 넣는 방법
Spring Framework | 2018. 1. 22. 21:11

[스프링 프레임워크] CharacterEncodingFilter를 통한 UTF-8 한글 인코딩 처리

스프링 인코딩 처리

스프링은 웹 요청과 응답에 대한 인코딩 처리를 위해 CharacterEncodingFilter를 제공합니다. 인코딩 필터의 경우 모든 프로젝트에서 사용 가능한 공통적인 기능이므로 스프링프레임워크 측에서 번거로움을 피하기 위해 제공하는 것 같습니다.

CharacterEncodingFilter 클래스는 Servlet 표준 스펙인 javax.servlet.Filter 인터페이스를 구현한 클래스이기 때문에 기존의 Servlet, JSP에서 사용하던 필터와 똑같이 사용 가능합니다.

web.xml을 통해 필터를 설정하는 경우

다음과 같이 사용 가능합니다. CharacterEncodingFilter를 필터로 등록해두고 <init-param>encoding 속성을 통해 인코딩 방식을 설정해줄 수 있습니다.

또한 <filter-mapping>을 통해 어느 요청경로에 대해 필터를 적용할 것인지에 대한 범위 설정이 가능합니다. 이 부분은 기존 필터와 사용방법이 전혀 다르지 않다는 것을 알 수 있습니다.

<filter>
     <filter-name>encoding</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>encoding</filter-name>
     <url-pattern>/*</url-pattern>
</filter-mapping>

응답 데이터 인코딩

기본적인 설정으로는 request 파라미터에 대한 인코딩만 처리하도록 되어있는데, 응답 데이터까지 인코딩을 처리하거나 인코딩 설정을 강제하는 경우에는 다음과 같이 추가적으로 forceEncoding 값을 true로 적용해주면 됩니다.

<init-param>
     <param-name>forceEncoding</param-name>
     <param-value>true</param-value>
</init-param>

WebApplicationInitializer를 구현하여 설정하는 경우

서블릿 3.0에서부터는 web.xml 없이 웹어플리케이션 설정을 초기화하는 기능을 제공합니다. 스프링은 그런 서블릿 3.0 스펙을 이용하여 WebApplicationInitializer라는 인터페이스를 제공하여 웹어플리케이션이 초기화할 때의 동작을 정의할 수 있도록 하고 있습니다.

만약 WebApplicationInitializer에서 CharacterEncodingFilter를 적용하는 경우 다음과 같이 사용 가능합니다.

import javax.servlet.FilterRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.filter.CharacterEncodingFilter;

public class MyWebAppInitializer implements WebApplicationInitializer {

     @Override
     public void onStartup(ServletContext servletContext) throws ServletException {
           FilterRegistration charEncodingFilterReg = servletContext.addFilter("CharacterEncodingFilter", CharacterEncodingFilter.class);
           charEncodingFilterReg.setInitParameter("encoding", "UTF-8");
           charEncodingFilterReg.setInitParameter("forceEncoding", "true");
           charEncodingFilterReg.addMappingForUrlPatterns(null, true, "/*");

     }

}

CharacterEncodingFilter 내부 구조 및 동작원리 분석

마지막으로 CharacterEncodingFilter의 소스를 열어보면 다음과 같습니다. 위에서 이미 모든 것을 설명했지만 아주 간단하게 구현되어 있기 때문에 어떻게 동작하는지 궁금한 사람에게 유용할 것 같습니다.

package org.springframework.web.filter;
import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;


/**
 * Servlet Filter that allows one to specify a character encoding for requests.
 * This is useful because current browsers typically do not set a character
 * encoding even if specified in the HTML page or form.
 *
 * <p>This filter can either apply its encoding if the request does not already
 * specify an encoding, or enforce this filter's encoding in any case
 * ("forceEncoding"="true"). In the latter case, the encoding will also be
 * applied as default response encoding (although this will usually be overridden
 * by a full content type set in the view).
 *
 * @author Juergen Hoeller
 * @since 15.03.2004
 * @see #setEncoding
 * @see #setForceEncoding
 * @see javax.servlet.http.HttpServletRequest#setCharacterEncoding
 * @see javax.servlet.http.HttpServletResponse#setCharacterEncoding
 */
public class CharacterEncodingFilter extends OncePerRequestFilter {

     private String encoding;
     private boolean forceEncoding = false;

     /**
      * Set the encoding to use for requests. This encoding will be passed into a
      * {@link javax.servlet.http.HttpServletRequest#setCharacterEncoding} call.
      * <p>Whether this encoding will override existing request encodings
      * (and whether it will be applied as default response encoding as well)
      * depends on the {@link #setForceEncoding "forceEncoding"} flag.
      */
     public void setEncoding(String encoding) {
           this.encoding = encoding;
     }


     /**
      * Set whether the configured {@link #setEncoding encoding} of this filter
      * is supposed to override existing request and response encodings.
      * <p>Default is "false", i.e. do not modify the encoding if
      * {@link javax.servlet.http.HttpServletRequest#getCharacterEncoding()}
      * returns a non-null value. Switch this to "true" to enforce the specified
      * encoding in any case, applying it as default response encoding as well.
      */
     public void setForceEncoding(boolean forceEncoding) {
           this.forceEncoding = forceEncoding;
     }


     @Override
     protected void doFilterInternal(
                HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
                throws ServletException, IOException {
           if (this.encoding != null && (this.forceEncoding || request.getCharacterEncoding() == null)) {
                request.setCharacterEncoding(this.encoding);
                if (this.forceEncoding) {
                     response.setCharacterEncoding(this.encoding);
                }
           }
           filterChain.doFilter(request, response);
     }

}
도로락

도로락

Writer

IT, 프로그래밍, 컴퓨터 활용 정보 등을 위한 블로그