Servlet 采用 forward 时,页面出现汉字乱码问题的分析

来源:互联网 发布:同济医学院知乎 编辑:程序博客网 时间:2024/06/06 09:03

经常有人问到,在servlet里面forward到一个页面之后,浏览器总是汉字的乱码。经调试发现,是由于在servlet里面不能正确调用 response.getWriter()方法造成的。

servlet 如下,如果去掉注释,则会出现乱码

package test;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class TestServlet extends HttpServlet {
  @Override
  
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
//    PrintWriter out = response.getWriter();
    RequestDispatcher requestDispatcher = request.getRequestDispatcher("/test/test2.jsp");
    requestDispatcher.forward(request, response);
  }

}

曾经尝试增加如下语句,问题依然存在

package test;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class TestServlet extends HttpServlet {
  @Override
  
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
    PrintWriter out 
= response.getWriter();
    response.setCharacterEncoding(
"UTF-8");
    response.setContentType(
"text/html;charset=UTF-8");
    RequestDispatcher requestDispatcher 
= request.getRequestDispatcher("/test/test2.jsp");
    requestDispatcher.forward(request, response);
  }

}

去掉后,就可以正常显示汉字了,

再次测试,发现是语句的顺序有问题,需要调整为如下的代码即可

package test;

import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class TestServlet extends HttpServlet {
  @Override
  
public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
    response.setCharacterEncoding(
"UTF-8"); // 先指定输出流的编码
    PrintWriter out = response.getWriter(); // 再拿到输出对象
    response.setContentType("text/html;charset=UTF-8");
    RequestDispatcher requestDispatcher 
= request.getRequestDispatcher("/test/test2.jsp");
    requestDispatcher.forward(request, response);
  }

}

看来,response.getWriter() 在内部的实现上,影响了输出流的编码集。必须先指定编码集,再调用Writer才可以。

 

附test2.jsp的代码

<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%>
<pre>中文
<%="中文2"%>
</pre>

web.xml, 未使用任何过滤器 

<?xml version="1.0" encoding="UTF-8"?>
<web-app id="WebApp_ID" version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee"
  xmlns:xsi
="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation
="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
  
<display-name>www.java2000.net</display-name>
  
<welcome-file-list>
    
<welcome-file>index.html</welcome-file>
    
<welcome-file>index.htm</welcome-file>
    
<welcome-file>index.jsp</welcome-file>
    
<welcome-file>default.html</welcome-file>
    
<welcome-file>default.htm</welcome-file>
    
<welcome-file>default.jsp</welcome-file>
  
</welcome-file-list>
</web-app>