我在 Tomcat 5.0.28 上遇到自定义错误页面的问题。用日语写的错误页面变得不可读。 (喜欢...あいう -> ??????)
我的环境。
- Java Sun SDK 1.4
- Tomcat 5.0.28
我有一个 Java 应用程序,它有一个 servlet,可以将任何 URL 请求的扩展名从 .htm 转换为 .jsp。我的 JSP 是用日语编写的,因此需要对指定的 content-Type header 进行编码,而 servlet 提供了它。他们相处得很好。
我想向此应用添加自定义的日语 404 错误页面。但是那个 404 页面的日文只有在通过 servlet 访问时才变得不可读。在这种情况下,它看起来像丢失了一个编码指定的 Content-Type header (我在该页面上看到了一个 HTTP 请求 header )。通常 text/html; charset=Shift_JIS
,但是当不可读变成text/html
。
不是通过那个 servlet,Content-Type header 和往常一样,定制的 404 页面的日语是有效的。 servlet 仅映射到扩展名为 *.htm 的请求。
我在应用程序的 web.xml 上的错误页面设置:
<error-page>
<error-code>404</error-code>
<location>/404.jsp</location>
</error-page>
我的 servlet 源:
public class Converter extends HttpServlet {
public void init() throws ServletException {
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException {
response.setContentType("text/html; charset=Shift_JIS");
ServletContext context = getServletConfig().getServletContext();
PrintWriter out = response.getWriter();
String reqUrl = request.getServletPath();
String jspName = reqUrl.substring(1,reqUrl.indexOf("."));
RequestDispatcher dispatcher = context.getRequestDispatcher("/"+jspName+".jsp");
dispatcher.forward(request,response);
}
public void destroy() {
}
}
错误页面 JSP“404.jsp”:
<%@ page language="java" isErrorPage="true" %>
<%@ page contentType="text/html; charset=Shift_JIS" pageEncoding="Shift_JIS" %>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
</head>
<body>
test 404<br />
日本語出力テスト<br />
</body>
</html>
请求 URL 和输出(服务器上没有这样的 JSP/HTM 文件):
http://example.com/nonexisting.htm
(通过 servlet)
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
</head>
<body>
test 404<br />
????????<br />
</body>
</html>
http://example.com/nonexisting.jsp
(不通过 servlet)
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=Shift_JIS">
</head>
<body>
test 404<br />
日本語出力テスト<br />
</body>
</html>
这是我尝试过的一些测试。每个文件都用 Shift_JIS 编写并包含日语。
现有文件请求测试。
- mydomain.com/existing.jsp(不通过 servlet)-> 没问题。
- mydomain.com/existing.htm(通过 servlet)-> 没问题。
不存在的文件请求测试(当然,我的服务器上没有这样的文件。)。
- mydomain.com/nonexisting.jsp(不通过 servlet)-> 用日语显示自定义 404 页面,没问题。
- mydomain.com/nonexisting.htm(通过 servlet)-> 显示自定义 404 页面,但丢失了 Content-Type header 且日语字符不可读。
另外我试过:
- 我试过与 Tomcat 捆绑在一起的 CharacterEncodingFilter,但它也不起作用。配置为在/404.jsp 时将请求编码为 Shift_JIS,但结果与上述相同。
谢谢你耐心等待我糟糕的英语(>_<) 任何帮助将不胜感激。
已解决
只需删除从未使用过的 getWriter(),那么 404 页面将不再缺少编码指定的 Content-Type header 并起作用。
public class Converter extends HttpServlet {
public void init() throws ServletException {
}
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException {
response.setContentType("text/html; charset=Shift_JIS");
ServletContext context = getServletConfig().getServletContext();
//PrintWriter out = response.getWriter();
String reqUrl = request.getServletPath();
String jspName = reqUrl.substring(1,reqUrl.indexOf("."));
RequestDispatcher dispatcher = context.getRequestDispatcher("/"+jspName+".jsp");
dispatcher.forward(request,response);
}
public void destroy() {
}
}
最佳答案
一般错误分为两种:
404 响应有一个 Content-Type header ,说明它是 charset=Shift_JIS 但它实际上编码不同或已损坏。假设 404.jsp 在磁盘上被正确编码,当它被加载到一个字符串中时它可能被破坏或者当字符串被写入 HTTP 响应时被转换。您在哪里将 Reader 和/或 Writers 的编码设置为 Shift_JIS?
404 响应编码为 Shift_JIS,但 Content-Type header 指定不同的 charset(或无,默认为 ISO-8859-1)。您的 doGet() 方法似乎对 200 个响应做了正确的事情,但 404 错误可能采取不同的路径。
显然,查看 404 响应的 HTTP header 会提供很多信息。您还应该调试应用程序以检查如何处理 404 响应。
关于java - 仅当从 servlet 访问时,带有日语的自定义 404 错误页面在 Tomcat 5 上变得不可读,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20349235/