회사에서 Spring Legacy 프로젝트(= Spring Boot 안 쓰는 프로젝트)를 사용 중이다.
그런데 이상하게 tomcat default error
페이지의 내용이 인코딩이 깨져서 보였다.
분명 tomcat vm option
에 -Dfile.encoding=UTF-8
까지 했고,
web.xml 에 org.springframework.web.filter.CharacterEncodingFilter
도 있었다.
하지만 시간이 지나고 나중에 더 자세히 알아보니 web.xml
에 작성된 CharacterEncodingFilter
필터의 속성인 forceEncoding
를 true
로 세팅하지 않은 상태였다.
세팅하고 나니 tomcat default error 페이지의 인코딩 깨짐문제가 사라졌다.
대체 forceEncoding=true
가 어떤 분기 처리를 하길래 이런걸까?
그에 대한 코드와 답변은 아래와 같다.
public class CharacterEncodingFilter extends OncePerRequestFilter {
// 1. CharacterEncodingFilter 멤버 변수
// 1-1. 실제 사용할 인코딩, ex: "UTF-8"
private String encoding;
// 1-2. encoding 으로 지정한 인코딩 방식을 Request 에 적욜할지 여부
private boolean forceRequestEncoding = false;
// 1-3. encoding 으로 지정한 인코딩 방식을 Response 에 적욜할지 여부
private boolean forceResponseEncoding = false;
// ...중간 생략...
// 2. HttpServletRequest, HttpServletResponse 모두 인코딩 적용
public void setForceEncoding(boolean forceEncoding) {
this.forceRequestEncoding = forceEncoding;
this.forceResponseEncoding = forceEncoding;
}
// 3. HttpServletResquest 만 인코딩 적용
public void setForceRequestEncoding(boolean forceRequestEncoding) {
this.forceRequestEncoding = forceRequestEncoding;
}
// 4. HttpServletResponse 만 인코딩 적용
public void setForceResponseEncoding(boolean forceResponseEncoding) {
this.forceResponseEncoding = forceResponseEncoding;
}
// 5. 실제 인코딩 적용 메소드
@Override
protected void doFilterInternal(
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
// 5-1. 먼저 지정한 인코딩(ex: "UTF-8")을 조회
String encoding = getEncoding();
// 5-2. 지정한 인코딩이 null 이 아니면...
if (encoding != null) {
// 5-3. forceRequestEncoding = true 또는
// 5-4. HttpServletRequest.getCharacterEncoding 가 null 이면
if (isForceRequestEncoding() || request.getCharacterEncoding() == null) {
// 5-5. Request에 encoding 적용!
request.setCharacterEncoding(encoding);
}
// 5-6. 만약에 forceResponseEncoding = true 라면...
if (isForceResponseEncoding()) {
// 5-7. Response 에 encoding 적용!
response.setCharacterEncoding(encoding);
}
}
// 다음 필터로 요청 위임
filterChain.doFilter(request, response);
}
}
ps. 이게 아무래도 web.xml 에 작성되어 있는 버전과 tomcat 버전 등이 영향을 주는 듯하다. 집에서는 굳이
forceEncoding=true
를 안 줘도 잘 된다.