zoukankan      html  css  js  c++  java
  • getOutputStream和getWriter在servlet中的区别

    response输出数据时的细节:

    (1)getOutputStream和getWriter这两个方法互相排斥,调用了其中的任何一个方法后,就不能再调用另一方法。 

    (2)Servlet程序向ServletOutputStream或PrintWriter对象中写入的数据将被Servlet引擎从response里面获取,Servlet引擎将这些数据当作响应消息的正文,然后再与响应状态行和各响应头组合后输出到客户端。

    (3)Serlvet的service方法结束后,Servlet引擎将检查getWriter或getOutputStream方法返回的输出流对象是否已经调用过close方法,如果没有,Servlet引擎tomcat将调用close方法关闭该输出流对象。

     另外参考这篇文档:response细节,重定向的用处和getWriter/getOutputStream的用法冲突的处理http://blog.csdn.net/xh16319/article/details/8449255

    1.重定向的实现:

     

    [java] view plain copy
     
    1. //和下句代码可互换位置,此两行相当于response.sendRedirect("");  
    2.     response.setStatus(302);  
    3.     //或者"location.jsp"  
    4.     response.setHeader("location","/HTTPHeader/location.jsp");  

    2.重定向的用处:

     

       一般情况下尽量不要用重定向,因为其会向服务器发送两次请求,增加服务器的负荷,并且会产生两个request和response对,除了特殊的场合:如:

        (1)用户登录成功后跳转至首页,如果用转发的话,那么用户无法从地址栏上看到首页地址

        (2)购物时,点击"加入购物车"按钮,然后就转向“显示购物车商品的页面showCar.jsp”,如果使用转发技术的,那么在“showCar.jsp”页面上如果刷新页面的话,则就会将“加入购物车的事件在作一次”。

        (3)在表单提交后(get和post方式都是一样),如果想跳转至某页面,如果用转发的话,则转至页面后,如果刷新页面,则会造成表单重复提交:

    如:当提交以post方式的表单后,如果刷新页面:

    当点击重试后:

    提交表单后,如果改为重定向到该页面,则刷新页面也只是刷新该页面,而不会造成表单重复提交

    3. getOutputStream和getWriter互斥问题:

         这两个方法互相排斥,调用了其中的任何一个方法后,就不能再调用另一方法。

        如:ExpiresServlet:

     

    [java] view plain copy
     
    1. public void doGet(HttpServletRequest request, HttpServletResponse response)  
    2.         throws ServletException, IOException {  
    3.        //设置缓存时间为1小时:时间单位为毫秒  
    4.      response.setDateHeader("Expires", System.currentTimeMillis()+1000*3600);  
    5.      String data = "abcdefghigk";  
    6.      //response.getWriter().print(data);  
    7.      response.getOutputStream().write(data.getBytes());  
    8.      //jsp中是也PrintWriter对象输出内容的  
    9.      request.getRequestDispatcher("index.jsp").forward(request, response);//改为response.sendRedirect("index.jsp");则不会抛该异常  
    10. }  

    如果访问该Servlet,则会抛出:java.lang.IllegalStateException: getOutputStream() has already been called for this response 异常


     

    这说明同一个response对象的这两个方法互相排斥,调用了其中的任何一个方法后,就不能再调用另一方法。

    解决办法:将request.getRequestDispatcher("index.jsp").forward(request, response);//改为response.sendRedirect("index.jsp");则不会抛该异常

    原因分析:改为重定向后,则 是两个response对象

    4.其他问题:

       (1)getOutputStream和getWriter方法分别用于得到输出二进制数据、输出文本数据的ServletOuputStream、Printwriter对象。
       (2)getOutputStream和getWriter这两个方法互相排斥,调用了其中的任何一个方法后,就不能再调用另一方法。  
       (3)Servlet程序向ServletOutputStream或PrintWriter对象中写入的数据将被Servlet引擎从response里面获取,Servlet引擎将这些数据当作响应消息的正文,然后再与响应状态行和各响应头组合后输出到客户端。
       (4)Serlvet的service方法结束后,Servlet引擎将检查getWriter或getOutputStream方法返回的输出流对象是否已经调用过close方法,如果没有,Servlet引擎将调用close方法关闭该输出流对象

  • 相关阅读:
    JavaScript递归方法 生成 json tree 树形结构数据
    分布式系统唯一ID生成方案汇总
    Twitter-Snowflake,64位自增ID算法详解
    手机端页面自适应解决方案—rem布局
    vue.js之路由
    kafka数据迁移实践
    mysql查询时强制区分大小写
    js加密参数传给后台,后台解密base64
    Target runtime com.genuitec.runtime.generic.jee60 is not defined
    怎么在点击浏览器前进、后退键时刷新页面而不读取缓存
  • 原文地址:https://www.cnblogs.com/pxffly/p/8440659.html
Copyright © 2011-2022 走看看