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 plaincopy

  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. }

输出

getOutputStream

zh_cn

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

[java] view plaincopy

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

输出

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

[java] view plaincopy

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

跳转到 ajax.jsp页面

sendRedirect("ajax.jsp")

[java] view plaincopy

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

重定向到ajax.jsp页面

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

两个响应情况

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

getWriter和getOutputStream

[java] view plaincopy

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

输出

抛出 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 plaincopy

  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. request.getRequestDispatcher("ajax.jsp").forward(request, response);
  11. }

输出

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

getWriter和redirect

[java] view plaincopy

  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. // 带上response.sendRedirect 时,直接跳转到ajax.jsp
  11. response.sendRedirect("ajax.jsp");
  12. }

输出

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

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

[java] view plaincopy

  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. request.getRequestDispatcher("ajax.jsp").forward(request, response);
  12. }

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

同时,后台会出现异常

[java] view plaincopy

  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 plaincopy

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

前台页面依然出现

同时后台会出现

[java] view plaincopy

  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 plaincopy

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

输出

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

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

时间: 2024-08-24 09:40:39

servlet的四种响应的相关文章

SpringMVC四种响应传值的方式

1.返回值为void类型 使用方法的参数requesr和response进行数据分享和页面跳转 @RequestMapping("/test1") public void test1(HttpServletRequest request, HttpServletResponse response) throws Exception{ //通过request和response控制页面和共享数据 request.setAttribute("msg","你好,太

你知道web项目中Http请求与响应的四种情况吗

[四种情况]: HttpRequest.HttpResponse.HttpServletRequest.HttpServletResponse[什么是HTTP?]超文本传输协议(HyperText Transfer Protocol -- HTTP)是一个设计来使客户端和服务器顺利进行通讯的协议.HTTP在客户端和服务器之间以request-response protocol(请求-回复协议)工作.[Http常用的两个方法]get - 从指定的服务器中获取数据post - 提交数据给指定的服务器

JSP内置对象——九大内置对象简介与四种作用域范围以及Web程序的请求和响应模式

最近在学习JSP相关基础知识,我们都知道JSP当中存在一组不使用new关键字就可以在脚本和表达式中使用的对象,在Web开发中经常使用.为了能更好的理解这些对象,在此对JSP内置对象作一些归纳. 目录: JSP内置对象——九大内置对象简介与四种作用域范围以及Web程序的请求和响应模式 JSP内置对象——out(待更新) JSP内置对象——request/response(待更新) JSP内置对象——session(待更新) JSP内置对象——application(待更新) JSP内置对象——其他

Android学习—Button的四种OnClick响应方法

在Android或Java开发中,对于button的OnClickListener有下面四种实现方式,可以根据需要选择合适的用法. 方法一: 适合场景:通用  Button bt_Demo = (Button)findViewById(R.id.bt_Demo);  bt_Demo.setOnClickListener(new OnClickListener()  {   @Override   public void onClick(View v)   {    //响应Clicked事件  

httpClient Post例子,Http 四种请求访问代码 HttpGet HttpPost HttpPut HttpDelete

httpclient post方法 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 //----1. HttpPost request = new HttpPost(url); // 先封装一个 JSON 对象 JSONObject param = new JSONObject(); param.put("name", "rarnu"); param.put("password", "123456"

06.实现servlet的几种方式,以及接口或者类之间的关系

接口:Servlet.ServletConfig.ServletRequest.ServletResponse.HttpServletRequest.HttpServletResponse.ServletContext 类:HttpServlet(抽象类).GenericServlet(抽象类) 来张关系图 ServletContext: ServletContext的对象是application是在项目初始化时被创建的.故servletContext随着应用初始化而被创建,随着应用的结束而被销

JSP九大内置对象和四种属性范围解读

林炳文Evankaka原创作品.转载请注明出处http://blog.csdn.net/evankaka 摘要:本文首先主要解说了JSP中四种属性范围的概念.用法与实例. 然后在这个基础之上又引入了九大内置对象,并对这几大内置对象一个一个的进行分析的解读.内容非常具体,例子都附有代码和执行的结果截图. 本文project下载 一.四种属性范围 1.1.在JSP中提供了四种属性保存范围 page:在一个页面内保存属性.跳转之后无效request:在一次服务请求范围内.server跳转后依旧有效se

四种会话跟踪技术

会话跟踪是一种灵活.轻便的机制,它使Web上的状态编程变为可能.HTTP是一种无状态协议,每当用户发出请求时,服务器就会做出响应,客户端与服务器之间的联系是离散的.非连续的.当用户在同一网站的多个页面之间转换时,根本无法确定是否是同一个客户,会话跟踪技术就可以解决这个问题.当一个客户在多个页面间切换时,服务器会保存该用户的信息.有四种方法可以实现会话跟踪技术:URL重写.隐藏表单域.Cookie.Session. 1).隐藏表单域:<input type="hidden">

SpringMVC的四种HandlerMapping

1:基础配置 (1)pom.xml <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">