스프링 인코딩 처리
스프링은 웹 요청과 응답에 대한 인코딩 처리를 위해 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);
}
}
출처: https://dololak.tistory.com/123 [코끼리를 냉장고에 넣는 방법]