我最近遇到了一个由 servlet 生成的网站的编码问题,如果 servlet 部署在 Tomcat 下,而不是 Jetty 下,就会发生这种情况。我对此做了一些研究,并将问题简化为以下 servlet:
public class TestServlet extends HttpServlet implements Servlet {
@Override
public void service(HttpServletRequest request, HttpServletResponse response) throws IOException {
response.setContentType("text/plain");
Writer output = response.getWriter();
output.write("öäüÖÄÜß");
output.flush();
output.close();
}
}
如果我在 Jetty 下部署它并将浏览器指向它,它会返回预期的结果。数据以 ISO-8859-1 形式返回,如果我查看 header ,则 Jetty 返回:
Content-Type: text/plain; charset=iso-8859-1
浏览器从这个 header 中检测编码。如果我在 Tomcat 中部署相同的 servlet,浏览器会显示奇怪的字符。但是 Tomcat 也将数据返回为 ISO-8859-1,不同之处在于,没有 header 说明它。所以浏览器必须猜测编码,这就出错了。
我的问题是,Tomcat 的这种行为是正确的还是错误?如果它是正确的,我怎样才能避免这个问题?当然,我总是可以将 response.setCharacterEncoding("UTF-8");
添加到 servlet,但这意味着我设置了一个固定的编码,浏览器可能理解也可能不理解。如果没有浏览器但另一个服务访问 servlet,则问题更相关。那么我应该如何以最灵活的方式处理问题呢?
最佳答案
如果您不指定编码,Servlet 规范需要 ISO-8859-1。但是,据我所知,它不需要容器在内容类型中设置编码,至少如果您将其设置为“text/plain”则不需要。规范是这样说的:
Calls to setContentType set the character encoding only if the given content type string provides a value for the charset attribute.
换句话说,只有当你这样设置内容类型时
response.setContentType("text/plain; charset=XXXX")
设置字符集需要 Tomcat。不过,我还没有尝试过这是否有效。
一般来说,我建议始终将编码设置为 UTF-8(因为它造成的麻烦最少,至少在浏览器中是这样),然后,对于文本/纯文本,明确说明编码,以防止浏览器使用系统默认值。
关于java - 为什么 Tomcat 没有响应设置编码?我该如何处理?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2509626/