HttpServletResponse的getWriter()和getOutputStream()详解

关于getWriter()和getOutputStream的理解

最近在做一个文件上传下载时遇到了一个问题,HttpServletResponse的实例对象在获取输出流时有两种方式,即getWriter()和getOutputStream(),但是这两种方式有什么联系和区别呢?

①PrintWriter out=response.getWriter();//out对象用于处理字符流数据。
②ServletOutputStream os=response.getOutputStream();//os用于输出字符流数据或者二进制的字节流数据都可以。

我们可以简单的将这两种方法理解为字节流FileOutputStream和FileWriter的区别。
下面我们看一下浏览器和服务器端是如何来关闭我们的response获得的输出流的。
在这里插入图片描述
注意:只要有一个流被创建了,并且已经完成了流的输出那么servlet容器就会将response对象交给服务器。
服务器将response对象中的内容做拆解响应给客户端。然后在检查该response的输出流有没有关闭,如果没有关闭就将输出流关闭。
当response再有另外一个流被创建并尝试做输出时就会发生异常。所以response的两个输出流只能使用一个,不能同时使用两个输出流。这也是为我们没有关闭流程序不出错的原因,当然更提倡我们自己关闭流。


此外,在jsp中,如果out变量是通过response.getWriter得到的,在程序中既用了response.getOutputStream,又用了out变量,则会抛出异常ERROR [Engine] StandardWrapperValve[jsp]: Servlet.service() for servlet jsp threw exception
java.lang.IllegalStateException: getOutputStream() has already been called for this response。

解决方案:

1.在程序中添加:

out.clear();
out = pageContext.pushBody();

2,不要在%][%之间写内容包括空格和换行符
3,在页面写入图片的时候,需要flush()

OutputStream output=response.getOutputStream();
output.flush();

4,在页面确定写入

meta http-equiv=”Content-Type” content=”text/html; charset=utf-8”

response.getOutputStream() 和 requonse.getWriter() 区别:

(1)使用tomcat5容器调用response.getOutputStream()方法即可实现,但调用requonse.getWriter()方法时,输出二进制数据时(图片等内容无法显示)则出现“getWriter() has already been called for this response”异常。
(2)使用tomcat6容器调用response.getOutputStream()方法时有中文字符会发生“java.io.CharConversionException:Not an ISO 8859-1 character:”异常,调用requonse.getWriter()方法时可实现文本字符串数据输出,调用response.getOutputStream()方法可现实字节流数据的输出。
就上述出现的问题进行分析研究,阅读了tomcat6的源代码发现,在调用response.getOutputStream()方法时会判断是否已调用了requonse.getWriter()方法;相反在调用requonse.getWriter()方法时会判断是否已调用了response.getOutputStream()方法。

你可能感兴趣的:(Java基础,servlet,java,服务器)