疯狂java


您现在的位置: 疯狂软件 >> 新闻资讯 >> 正文

HttpServletResponse的应用输出消息正文


 

 
例子 : 输出消息正文
1.  实例说明
 
在本例中,通过action请求参数来执行四个不同的代码段,以演示使用PrintWriter和ServletOutputStream输出中文信息时的区别。
 
2.  编写OutText类
 
public class OutText extends HttpServlet
{
    public void service(HttpServletRequest request, HttpServletResponse response)
            throws ServletException, IOException
    {
        String action = request.getParameter("action");
        if (action != null)
        {
            //  第1种情况
            if (action.equals("1"))
            {
                response.setContentType("text/html;charset=UTF-8");               
                PrintWriter out = response.getWriter();
                out.write("使用PrintWriter输出信息");
            }
            //  第2种情况
            else if (action.equals("2"))
            {
                ServletOutputStream sos = response.getOutputStream();
                OutputStreamWriter osw = new OutputStreamWriter(sos);
                osw.write("使用ServletOutputStream输出信息(未设置客户端和服务端编码)");
                osw.flush(); // 或调用sos.close();                
            }
            //  第3种情况
            else if (action.equals("3"))
            {
                ServletOutputStream sos = response.getOutputStream();
                sos.write("使用ServletOutputStream输出信息(未设置客户端)".getBytes("UTF-8"));
                sos.close(); // 或调用sos.flush();
            }
            //  第4种情况
            else if (action.equals("4"))
            {
                response.setContentType("text/html;charset=UTF-8");               
                ServletOutputStream sos = response.getOutputStream();               
                sos.write("使用ServletOutputStream输出信息".getBytes("UTF-8"));
                sos.close(); // 或调用sos.flush();
            }           
        }
    }
}
3.  配置OutText类
 
OutText类配置代码如下:
 
<servlet>
    <servlet-name>OutText</servlet-name>
    <servlet-class>chapter5.OutText</servlet-class>
</servlet>
<servlet-mapping>
    <servlet-name>OutText</servlet-name>
    <url-pattern>/OutText</url-pattern>
</servlet-mapping>
       
 
4.  测试程序
 
在浏览器地址栏中输入如下四个URL,并将浏览器的编码设置改为自动选择状态,看看会显示什么信息?
 
http://localhost:8080/demo/OutText?action=1
http://localhost:8080/demo/OutText?action=2
http://localhost:8080/demo/OutText?action=3
http://localhost:8080/demo/OutText?action=4
5.  程序总结
 
        在本例的代码中第1种情况和第4种情况都会正常显示中文,而当浏览器设为非GB2312编码格式时(如UTF-8),则第2种和第3种情况会显示乱码(但不会是“?”),只要将浏览器的编码格式设置正确(第2种情况设为GB2312,第3种情况设为UTF-8)就可正确显示中文了。在第4种情况, ServletOutputStream并不根据setContentType方法所设置的charset=UTF-8进行编码,因此,需要使用getBytes方法将中文字符串转换为UTF-8格式。然而这时必须让客户端浏览器也按着UTF-8格式来解析字符才确保正常显示中文信息。因此,setContentType方法就只剩下一个功能了,就是设置了客户端编码。所以在使用ServletOutputStream输出中文信息时,必须使用setContentType或addHeader方法来设置HTTP响应消息头的Content-Type字段才能保证正常显示中文信息。
 
从上面的例子可以总结出使用PrintWriter或ServletOutputStream的四点注意事项:
 
(1)PrintWriter和ServletOutputStream是互斥的,也就是说不能同时使用PrintWriter和ServletOutputStream向客户端输出信息。如果同时调用getWriter方法和getOutputStream方法,Servlet引擎会抛出java.lang.IllegalStateException异常。
 
(2)在使用PrintWriter输出中文时,会根据setCharacterEncoding方法或setContentType方法所设置的字符集编码对中文字符进行编码。而ServletOutputStream并不会考虑这个设置。要想使用ServletOutputStream向客户端输出指定编码格式的信息,需要使用String的getBytes方法来转换编码格式。
 
(3)如果未设置服务端编码,PrintWriter默认使用了ISO-8859-1编码格式,而ServletOutputStream使用了操作系统的默认编码格式,也就是GB2312。因此,如果在未设置服务端编码的情况下,PrintWriter输出的中文字符都被替换成了“?”,而使用ServletOutputStream是不会输出“?”的(当然,如果非要让ServletOutputStream输出“?”也是可以的,只要使用getBytes方法将字符串转换成ISO-8859-1或其他不支持中文信息的编码格式即可,但我想恐怕没人要这么做吧!)。
 
(4)在使用PrintWriter对象输出信息时,并不需要调用flush或close方法关闭PrintWriter对象。而在使用ServletOutputStream对象输出信息时,最后必须使用close方法关闭ServletOutputStream对象或使用flush方法刷新缓冲区,才能将信息输出到客户端。
 
        在Servlet中可以通过PrintWriter和ServletOutputStream向客户端输出信息。其中PrintWriter在前面已经使用过很多次了,它的主要功能是向客户端输出基于文本的信息。PrintWriter对象可以通过HttpServletResponse接口的getWriter方法获得。而ServletOutputStream一般用于向客户端输出基于字节流的信息。通过HttpServletResponse接口的getOutputStream方法可以获得ServletOutputStream对象。它们虽然都可以输出文本信息,但对中文编码的处理方式却不同。