经常有人问到,在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, 未使用任何过滤器