java - 仅当从 servlet 访问时,带有日语的自定义 404 错误页面在 Tomcat 5 上变得不可读

标签 java jsp tomcat servlets http-status-code-404

我在 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/

相关文章:

java - 带有 QueryDslPredicateExecutor 和加入集合的 Spring-Data-JPA

java - JRebel with maven for Java Web App 每次都需要全新安装,对吗?

通过 NDK 的 Android 客户端-服务器

java - Android Studio - 当 TextView 位于自定义 xml 文件时尝试使用代码更改 TextView 属性时,应用程序崩溃

java - Safari Activity 窗口 java applet 类未找到

java - 在 Java 中从方法中抛出异常记录参数值的简单方法

java - 渲染父 subview 导致StackOverflow异常

java - 使用 jsp、servlet 和 ajax 发表评论

java - JSP 应用程序的浏览器插件或调试面板

java - CORS 不适用于不同的网址