servlet的四种响应

在一个servlet的请求中,响应的方式的通常有四式,response.getWriter(),response.getOutputStream(),

request.getRequestDispatcher("ajax.jsp").forward(request, response) 和 response.sendRedirect("ajax.jsp") 。

其中

  • response.getWriter() 输出页面
  • response.getOutputStream() 输出二进制流文件
  • request.getRequestDispatcher("ajax.jsp").forward(request, response) 页面跳转
  • response.sendRedirect("ajax.jsp") 重定向


    这四种方式单独使用,大家应该都很熟悉,如果一个servlet里面写了两种响应,会出现什么情况呢,今天看一下写两个响应的现象分析。


servlet的四种响应


getWriter


getWriter 返回可将字符文本发送到客户端的 PrintWriter 对象。

[java]  view plain  copy
  1. /** 
  2.      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) 
  3.      */  
  4.     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  5.         // 单独这一块,输出Welcome to Servlet  
  6.         PrintWriter out = response.getWriter();  
  7.         out.println("<body><h1>");  
  8.         out.println("Welcome to Servlet");  
  9.         out.println("</h1></body>");  
  10.           
  11.     }  

输出 


getOutputStream


zh_cn
getOutputStream 返回适用于在响应中编写二进制数据的ServletOutputStream

[java]  view plain  copy
  1. /** 
  2.  * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) 
  3.  */  
  4. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  5.       
  6.     OutputStream os = response.getOutputStream();  
  7.     InputStream is = new FileInputStream(new File("D:\\pic\\P41004-154736.jpg"));  
  8.     byte[] buf = new byte[1024];  
  9.     while (is.read(buf) > 0) {  
  10.         os.write(buf);  
  11.     }  
  12.     os.flush();  
  13.     is.close();  
  14.     os.close();  
  15.       
  16. }  

输出



getRequestDispatcher("ajax.jsp").forward(request, response) 


[java]  view plain  copy
  1. /** 
  2.  * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) 
  3.  */  
  4. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  5.       
  6.     request.getRequestDispatcher("ajax.jsp").forward(request, response);  
  7.   
  8. }  

跳转到 ajax.jsp页面


sendRedirect("ajax.jsp")


[java]  view plain  copy
  1. /** 
  2.  * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) 
  3.  */  
  4. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  5.       
  6.     response.sendRedirect("ajax.jsp");  
  7.       
  8. }  

重定向到ajax.jsp页面



       上面采用forward跳转的时候,地址栏显示的是res请求,使用redirect重定向之后,等于重新发送了一个ajax.jsp的请求,URL地址栏变为了ajax.jsp


两个响应情况


一个servlet请求会有一个request请求和一个response响应,那如果一个response想响应两次呢?一般都是会出错的。代码中避免使用多个响应的情况。


getWriter和getOutputStream


[java]  view plain  copy
  1. /** 
  2.      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) 
  3.      */  
  4.     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  5.           
  6.         PrintWriter out = response.getWriter();  
  7.         out.println("<body><h1>");  
  8.         out.println("Welcome to Servlet");  
  9.         out.println("</h1></body>");  
  10.           
  11.         OutputStream os = response.getOutputStream();  
  12.         InputStream is = new FileInputStream(new File("D:\\pic\\P41004-154736.jpg"));  
  13.         byte[] buf = new byte[1024];  
  14.         while (is.read(buf) > 0) {  
  15.             os.write(buf);  
  16.         }  
  17.         os.flush();  
  18.         is.close();  
  19.         os.close();  
  20.           
  21.     }  

输出

抛出 getWriter() has already been called for this response 异常信息


上面介绍了单独使用getWriter和 getOutputStream的情况,分别返回响应页面和二进制流文件。

这两个方法都有几个共同的异常信息,IOException 和 IllegalStateException

getWriter的IllegalStateException异常描述:if thegetOutputStream method has already been called for this response object

getOutputStream的IllegalStateException异常描述:if thegetWriter method has been called on this response

这个IllegalStateException信息说明,这两个响应不可以同时使用,否则会出现IllegalStateException。



getWriter和forward


[java]  view plain  copy
  1. /** 
  2.      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) 
  3.      */  
  4.     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  5.         // 单独这一块,输出Welcome to Servlet  
  6.         PrintWriter out = response.getWriter();  
  7.         out.println("<body><h1>");  
  8.         out.println("Welcome to Servlet");  
  9.         out.println("</h1></body>");  
  10.           
  11.         request.getRequestDispatcher("ajax.jsp").forward(request, response);  
  12.           
  13.   
  14.     }  

输出 

没有输出Welcome to Servlet ,直接跳转到了ajax.jsp页面


getWriter和redirect


[java]  view plain  copy
  1. /** 
  2.      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) 
  3.      */  
  4.     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  5.         // 单独这一块,输出Welcome to Servlet  
  6.         PrintWriter out = response.getWriter();  
  7.         out.println("<body><h1>");  
  8.         out.println("Welcome to Servlet");  
  9.         out.println("</h1></body>");  
  10.           
  11.         // 带上response.sendRedirect 时,直接跳转到ajax.jsp  
  12.         response.sendRedirect("ajax.jsp");  
  13.     }  

输出 



    通过上面的getWriter和forward的例子和这里的getWriter和redirect的例子可以看出,getWriter只向页面输出内容,但并没有提交(commit)该响应。后续有可以提交响应的响应代码时,会覆盖掉getWriter的响应输出。


将上面的代码做一点修改,添加一行代码out.flush();

[java]  view plain  copy
  1. /** 
  2.      * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) 
  3.      */  
  4.     protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  5.         // 单独这一块,输出Welcome to Servlet  
  6.         PrintWriter out = response.getWriter();  
  7.         out.println("<body><h1>");  
  8.         out.println("Welcome to Servlet");  
  9.         out.println("</h1></body>");  
  10.         out.flush();  
  11.           
  12.         request.getRequestDispatcher("ajax.jsp").forward(request, response);  
  13.   
  14.     }  

out.flush() 方法会提交掉该response响应,此时页面响应为

同时,后台会出现异常

[java]  view plain  copy
  1. java.lang.IllegalStateException: Cannot forward after response has been committed  
  2.     at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:348)  
  3.     at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:338)  



getOutputStream和forward


[java]  view plain  copy
  1. /** 
  2.  * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) 
  3.  */  
  4. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  5.       
  6.     OutputStream os = response.getOutputStream();  
  7.     InputStream is = new FileInputStream(new File("D:\\pic\\P41004-154736.jpg"));  
  8.     byte[] buf = new byte[1024];  
  9.     while (is.read(buf) > 0) {  
  10.         os.write(buf);  
  11.     }  
  12.     os.flush();  
  13.     is.close();  
  14.     os.close();  
  15.       
  16.     request.getRequestDispatcher("ajax.jsp").forward(request, response);  
  17.   
  18. }  

前台页面依然出现

同时后台会出现

[java]  view plain  copy
  1. 严重: Servlet.service() for servlet [com.test.ResTest] in context with path [/servletDemo] threw exception  
  2. java.lang.IllegalStateException: Cannot forward after response has been committed  
  3.     at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:348)  
  4.     at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:338)  
  5.     at com.test.ResTest.doPost(ResTest.java:52)  
  6.     at com.test.ResTest.doGet(ResTest.java:34)  


RequestDispatcher 类的forward方法有个IllegalStateException异常

异常信息这样描述:if the response was already committed ,如果响应已经被提交。

这里例子说明getOutputStream,对前台进行了响应,并且提交了该响应。


getOutputStream和redirect


    出现与getOutputStream和forward中同样的结果,前台展现,后台出错


forward和redirect


[java]  view plain  copy
  1. /** 
  2.  * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) 
  3.  */  
  4. protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {  
  5.       
  6.     request.getRequestDispatcher("ajax.jsp").forward(request, response);  
  7.       
  8.     response.sendRedirect("ajax.jsp");  
  9. }  

输出


这个异常信息与前面的相同,就不再做分析了。


    经过上面的几个同时两个响应的例子,可以看出,一个servlet请求只能有一个响应,任何多个响应的代码都是错误的,都会出现IllegalStateException。也就是说,多个响应的场景是非法的,一个servlet一个响应就可以了,是它的标配。


http://blog.csdn.net/magi1201/article/details/45271987

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值