Servlet--HttpServletResponse的2个操作流的方法

前面已经说过无数多次了。我们的项目都是基于HTTP协议的一次请求。一次响应。实际编码中,我们在处理完逻辑后通常是跳转到一个页面上,或者用输出流返回json字符串。事实上跳转到一个页面往往也就是JSP,JSP执行在tomcat里面编译处理后返回响应。最后一步都是通过response获得输出流来返回到浏览器。这里总结下response的2个输出流。
  • 首先我们翻下API:
public ServletOutputStream getOutputStream() throws IOException;
返回一个记录二进制的响应数据的输出流。
注意:假设这个响应对象已经调用getWriter,将会抛出IllegalStateException。


public PrintWriter getWriter() throws IOException;
这种方法返回一个PringWriter对象用来记录格式化的响应实体。

假设要反映使用的字符编码,必须改动响应的MIME类型。


注意:在调用这种方法之前,必须设定响应的content类型。

假设没有提供这种编码类型,会抛出一个UnsupportedEncodingException。假设这个响应对象已调用getOutputStream,会抛出一个getOutputStream。

  • 对照上面的2个方法我们来整理一下:
1,getWriter()用于向客户机回送字符数据
2。getOutputStream()用于向客户机回送字符数据,也能够回送字节数据

  • 那么我们应该怎么选择这2种输出流呢?
假设我们回送字符数据,就用getWriter,效率高
假设我们回送的是字节数据,也就仅仅能用getOutputStream了。




上面API上已经说的非常明确。这2个方法不能同一时候使用。看以下的代码:

package linkin;

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

/**
 * @author LinkinPark
 * @author 2015-7-10
 * @Descri HttpServletResponse的2个输出流
 */
public class LinkinServlet extends HttpServlet
{
	private static final long serialVersionUID = 1L;

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
	{
		//resp.setContentType("text/html;charset=UTF-8");
		resp.getWriter().write("林肯公园");
		resp.getOutputStream().write("林肯公园".getBytes());
	}

	@Override
	protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException
	{
		this.doGet(req, resp);
	}
	
}

我们如今訪问下:http://localhost:8080/linkin/LinkinServlet结果报错了,报错说:

getWriter() has already been called for this response

什么意思呢?就是说上面第一次使用流返回响应已经将这个流关闭了。这个是Servlet引擎自己主动帮我们做的,所以就不能第2次再去获得这个流来操作了。当然这里我们也能够自己来将输出流关闭,只是即使我们不关闭,引擎也会自己主动帮我关闭了。




原文地址:https://www.cnblogs.com/mthoutai/p/6868368.html