V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
V2EX 提问指南
yvanhe
V2EX  ›  问与答

求助 JSP 乱码的问题

  •  1
     
  •   yvanhe · 2016-03-07 22:32:38 +08:00 · 2204 次点击
    这是一个创建于 3181 天前的主题,其中的信息可能已经有所发展或是发生改变。
    写了个登录返回结果的 demo ,结果一直出现乱码问题。 Google 百度搜一圈也没看到靠谱答案,以为是项目文件编码有问题,删了重建一个只有一个 jsp 和一个 servlet 的项目。整个项目包括 JSP 都是设置了 UTF-8 。
    发现还是有问题。
    在 jsp 里写了如下内容:
    <body>
    <%out.println("测试");%>
    <form action="test">
    <input name="name" type="text" />
    <input type="submit" />
    </form>
    </body>
    打开 test.jsp 的时候显示正常。
    点击按钮请求 servlet ,在 servlet 的 service()方法中调用 RequestDisptacher 的 forward 方法回到 test.jsp 后,就显示不正常,“测试”两个字显示“??”。
    看了响应头的 ContentType 编码是 iso8859-1
    JSP 的 ContentType 我都设置了 UTF-8 ,为什么响应的 ContentType 还是 iso8859-1 呢?
    在 service()方法里用 response.setContentType()方法也没用。
    有没有不修改 tomcat 配置解决这个问题的方法?

    折腾来折腾去,编码问题都把我脑袋变成浆糊了。
    第 1 条附言  ·  2016-03-08 10:20:07 +08:00
    解决了,万万没想到 Bug 产生的原因是这样的:
    用 Eclipse 新建 servlet 的时候, doGet()里自动生成了一句代码:

    response.getWriter().append("Served at: ").append(request.getContextPath());

    删掉这行代码,或者在这行代码前面加上 response.setCharacterEncoding("UTF-8");
    乱码就解决了……
    Response Headers 里面的 Content-Type 就变回了"text/html;charset=UTF-8"而不是之前诡异的"iso8859-1"

    我在网上搜到
    “设置服务器端的编码
    response.setCharacterEncoding("utf-8 ”);
    默认是 ISO-8859-1 ;该方法必须在 response.getWriter()之前进行设置”

    之前 response.setCharacterEncoding("UTF-8");是加在 service()方法里的,没起作用,可能因为 doGet()方法调用在 service()方法之前,那时候已经调用了 response.getWriter()方法,编码变成了默认的 iso8859-1 。

    为什么 response.setCharacterEncoding("utf-8 ”);必须在 response.getWriter()之前进行设置?

    PS :楼主的故事告诉我们,求助解决 Bug 的时候,代码要贴全……
    19 条回复    2016-03-08 10:30:49 +08:00
    Strikeactor
        1
    Strikeactor  
       2016-03-07 22:37:45 +08:00   ❤️ 1
    你输出的内容要不加个<meta charset="utf-8"> 试试。。
    xmh51
        2
    xmh51  
       2016-03-07 22:39:49 +08:00
    额,你这都不是标准 html 网页吧。
    yvanhe
        3
    yvanhe  
    OP
       2016-03-07 22:42:01 +08:00
    @Strikeactor 在哪加? JSP 里有写<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 请求 servlet 后什么也没做,就是 forward 到原先的这个 jsp
    yvanhe
        4
    yvanhe  
    OP
       2016-03-07 22:42:27 +08:00
    @xmh51 我没贴全代码 但网页是完整的
    AccIdent
        5
    AccIdent  
       2016-03-07 22:47:43 +08:00   ❤️ 1
    目测是 web 容器的问题
    Strikeactor
        6
    Strikeactor  
       2016-03-07 22:48:10 +08:00
    @yvanhe 加你输出的 HTML 的 head 里。。

    yvanhe
        7
    yvanhe  
    OP
       2016-03-07 22:50:36 +08:00
    @Strikeactor
    加了,还是一样,你这句应该和我原先写的<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">效果一样吧。。
    yvanhe
        8
    yvanhe  
    OP
       2016-03-07 22:53:27 +08:00
    @AccIdent 用的 apache-tomcat-7.0.53
    yvanhe
        9
    yvanhe  
    OP
       2016-03-07 23:23:06 +08:00
    网页里是<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
    Response Headers 里是 Content-Type:text/html;charset=ISO-8859-1
    Sharuru
        10
    Sharuru  
       2016-03-07 23:24:22 +08:00 via Android
    试试 tomcat 8
    yvanhe
        11
    yvanhe  
    OP
       2016-03-07 23:41:26 +08:00
    @Sharuru 试了 6 、 7 、 8 ,都这样
    hpeng
        12
    hpeng  
       2016-03-07 23:55:51 +08:00 via iPhone   ❤️ 1
    Tomcat 里面配置编码
    SoloCompany
        13
    SoloCompany  
       2016-03-08 00:12:17 +08:00   ❤️ 1
    不贴 Servlet 源代码的都是耍流氓
    我告诉你个不用管你 Servlet 代码的方法,就是在 test.jsp 前面加上 ContentType 强制
    <c:set target=“${pageContent.response}” property=“ charset ” value=“ UTF-8 ” />
    加 meta 是没有用的,因为 Content-Type 声明的 charset 是最高优先级的,请参考 HTML specification
    yvanhe
        14
    yvanhe  
    OP
       2016-03-08 00:21:16 +08:00 via Android
    @SoloCompany servlet 里就一句 forward 到 test.jsp 的代码
    DRcoding
        15
    DRcoding  
       2016-03-08 09:08:00 +08:00   ❤️ 1
    修改 server.xml
    <Connector port="8080" protocol="HTTP/1.1"
    connectionTimeout="20000"
    redirectPort="8443" URIEncoding="utf-8" />
    yvanhe
        16
    yvanhe  
    OP
       2016-03-08 09:48:29 +08:00
    @DRcoding
    @hpeng
    冏了 修改了 server.xml URIEncoding="utf-8" 重启了 tomcat 也还是原来那样
    yvanhe
        17
    yvanhe  
    OP
       2016-03-08 10:00:36 +08:00
    @SoloCompany

    我在 jsp 里加了
    <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
    <%@ page isELIgnored="false"%>
    <c:set target= "${pageContent.response}" property="charset" value="UTF-8" />

    报错, javax.servlet.jsp.JspTagException
    yvanhe
        18
    yvanhe  
    OP
       2016-03-08 10:19:04 +08:00
    @Strikeactor
    @xmh51
    @AccIdent
    @Sharuru
    @hpeng
    @SoloCompany

    解决了,万万没想到 Bug 产生的原因是这样的:
    用 Eclipse 新建 servlet 的时候, doGet()里自动生成了一句代码:

    response.getWriter().append("Served at: ").append(request.getContextPath());

    删掉这行代码,或者在这行代码前面加上 response.setCharacterEncoding("UTF-8");
    乱码就解决了……
    Response Headers 里面的 Content-Type 就变回了"text/html;charset=UTF-8"而不是之前诡异的"iso8859-1"

    我在网上搜到
    “设置服务器端的编码
    response.setCharacterEncoding("utf-8 ”);
    默认是 ISO-8859-1 ;该方法必须在 response.getWriter()之前进行设置”

    之前 response.setCharacterEncoding("UTF-8");是加在 service()方法里的,没起作用,可能因为 doGet()方法调用在 service()方法之前,那时候已经调用了 response.getWriter()方法,编码变成了默认的 iso8859-1 。

    为什么 response.setCharacterEncoding("utf-8 ”);必须在 response.getWriter()之前进行设置?
    xmh51
        19
    xmh51  
       2016-03-08 10:30:49 +08:00   ❤️ 1
    @yvanhe 为什么 response.setCharacterEncoding("utf-8 ”);必须在 response.getWriter()之前进行设置?,因为 response.getWriter() 就代表输出 response 内容了。 在这之后的设置和之前输出的内容无关。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1326 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 23:45 · PVG 07:45 · LAX 15:45 · JFK 18:45
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.