1. 현상
개발 환경 혹은 타 WAS 에서 잘 사용되던 JSP 를 Tomcat 에 배포하여 처리하려는데 "Page directive: illegal to have multiple occurrences of contentType with different values" 이 발생할 수 있다.
그리고 예를 들어, (old: text/html;charset=euc-kr, new: text/html;charset=EUC-KR) 가 따라올 것이다.
이런 경우 해당 JSP 에 contentType 이 중복 선언되어 있을 것이다. 혹은 JSP 내에 다른 JSP 가 include 되어 있고 두 JSP 에 각각 contentType 이 선언되어 있을 것이다. 그리고 가장 중요한 것은, 그 두 개 이상의 contentType 이 다르다는 것이다.
- old: text/html;charset=euc-kr
- new: text/html;charset=EUC-KR
와 같이 대소문자 차이, 혹은 공백 차이, 아니면 아예 charset 의 차이 등등 분명히 차이가 있을 것이다.
2. 원인
왜 그럴까?
Tomcat 7.0.57 소스 기준으로 org.apache.jasper.compiler 패키지의 Validator.java 를 보자.
private static final JspUtil.ValidAttribute[] pageDirectiveAttrs = { new JspUtil.ValidAttribute("language"), new JspUtil.ValidAttribute("extends"), new JspUtil.ValidAttribute("import"), new JspUtil.ValidAttribute("session"), new JspUtil.ValidAttribute("buffer"), new JspUtil.ValidAttribute("autoFlush"), new JspUtil.ValidAttribute("isThreadSafe"), new JspUtil.ValidAttribute("info"), new JspUtil.ValidAttribute("errorPage"), new JspUtil.ValidAttribute("isErrorPage"), new JspUtil.ValidAttribute("contentType"), new JspUtil.ValidAttribute("pageEncoding"), new JspUtil.ValidAttribute("isELIgnored"), new JspUtil.ValidAttribute("deferredSyntaxAllowedAsLiteral"), new JspUtil.ValidAttribute("trimDirectiveWhitespaces") }; public void visit(Node.PageDirective n) throws JasperException { JspUtil.checkAttributes("Page directive", n, pageDirectiveAttrs, err); // JSP.2.10.1 Attributes attrs = n.getAttributes(); for (int i = 0; attrs != null && i < attrs.getLength(); i++) { String attr = attrs.getQName(i); String value = attrs.getValue(i); if ("language".equals(attr)) { ...... } else if ("contentType".equals(attr)) { if (pageInfo.getContentType() == null) { pageInfo.setContentType(value); } else if (!pageInfo.getContentType().equals(value)) { err.jspError(n, "jsp.error.page.conflict.contenttype", pageInfo.getContentType(), value); } }
관련 참고.
< JspUtil.java >
public static void checkAttributes(String typeOfTag, Node n, ValidAttribute[] validAttributes, ErrorDispatcher err) throws JasperException { ... } public static class ValidAttribute { String name; boolean mandatory; public ValidAttribute(String name, boolean mandatory) { this.name = name; this.mandatory = mandatory; } public ValidAttribute(String name) { this(name, false); } }
한참 후에 업데이트. 인터파크 쇼핑하다가 반가운 오류를 발견하여 공유한다.
org.apache.jasper.JasperException: /dsearch/include/common.jsp (line: 1, column: 2) Page directive: illegal to have multiple occurrences of contentType with different values (old: text/html; charset=euc-kr, new: text/html;charset=euc-kr)
text/html; 뒤에 공백때문에..