定义

  请求包含是指将另一个Servlet的请求处理流程包含进来。
  请求转发是指将请求转发给别的Servlet处理。


实现

  实现请求包含和请求转发,可以使用HttpServletRequest的getRequestDispatcher()方法取得RequestDispatcher接口的实现对象实例,调用时传入请求、响应对象即可。
  取得RequestDispatcher还有两个方式,通过ServletContext的getRequestDispatcher()或getNamedDispatcher()。


demo

  1. package com.test;
  2.  
  3. import javax.servlet.RequestDispatcher;
  4. import javax.servlet.ServletException;
  5. import javax.servlet.annotation.WebServlet;
  6. import javax.servlet.http.HttpServlet;
  7. import javax.servlet.http.HttpServletRequest;
  8. import javax.servlet.http.HttpServletResponse;
  9. import java.io.IOException;
  10. import java.io.PrintWriter;
  11.  
  12. @WebServlet({"/some.controller", "/world"})
  13. public class Some extends HttpServlet {
  14. @Override
  15. protected void doGet(HttpServletRequest request, HttpServletResponse response)
  16. throws ServletException, IOException {
  17. PrintWriter out = response.getWriter();
  18. out.println("Some do one...");
  19. RequestDispatcher dispatcher = request.getRequestDispatcher("other.view");
  20. // 请求包含
  21. dispatcher.include(request, response);
  22. // 请求转发
  23. // dispatcher.forward(request, response);
  24. out.println("Some do two...");
  25. }
  26. }

Some.java

  1. package com.test;
  2.  
  3. import javax.servlet.ServletException;
  4. import javax.servlet.annotation.WebServlet;
  5. import javax.servlet.http.HttpServlet;
  6. import javax.servlet.http.HttpServletRequest;
  7. import javax.servlet.http.HttpServletResponse;
  8. import java.io.IOException;
  9. import java.util.Arrays;
  10.  
  11. @WebServlet({"/other.view", "/view"})
  12. public class Other extends HttpServlet {
  13. @Override
  14. protected void doGet(HttpServletRequest request, HttpServletResponse response)
  15. throws ServletException, IOException {
  16.  
  17. response.getWriter().println("Other do one...");
  18. }
  19. }

Other.java

请求转发 forward 的响应结果是:

  Other do one...

请求包含 include 的响应结果是:

  Some do one...
  Other do one...
  Some do two...


区别

  forward:目前的Servlet不能有任何响应确认,如果在目前的Servlet中通过响应对象设置了一些响应但未确认(响应缓冲区未满或未调用任何清除方法),则所有响应设置会被忽略,如果已经有响应确认且调用了forward()方法,则会抛出IllegalStateException。

  include:被包含的Servlet中任何对请求标头的设置都会被忽略。但被包含的Servlet中可以使用getSession()方法取得HttpSession对象。


相同点

1、在取得RequestDispatcher时,也可以包括查询字符串。
  例如:req.getRequestDispatcher("other.view?data=123456").include(req, resp);
  这样在被包含或转发的Servlet中就可以使用getParameter("data")取得请求参数值。
2.查询字符串的方式,仅适用于传递字符串值给另一个Servlet;如果有必须共享的“对象”,可以设置给请求对象成为属性。
  HttpServletRequest上与请求范围属性有关的几个方法如下。
  setAttribute():指定名称与对象设置属性。
  getAttribute():指定名称取得属性。
  getAttributeNames():取得所有属性名称。
  removeAttribute():指定名称移除属性。

example:

  1. package com.test;
  2.  
  3. import javax.servlet.RequestDispatcher;
  4. import javax.servlet.ServletException;
  5. import javax.servlet.annotation.WebServlet;
  6. import javax.servlet.http.HttpServlet;
  7. import javax.servlet.http.HttpServletRequest;
  8. import javax.servlet.http.HttpServletResponse;
  9. import java.io.IOException;
  10. import java.io.PrintWriter;
  11.  
  12. @WebServlet({"/some.controller", "/world"})
  13. public class Some extends HttpServlet {
  14. @Override
  15. protected void doGet(HttpServletRequest request, HttpServletResponse response)
  16. throws ServletException, IOException {
  17. request.setAttribute("setAttr", new int[]{1, 2, 3});
  18.  
  19. PrintWriter out = response.getWriter();
  20. out.println("Some do one...");
  21. RequestDispatcher dispatcher = request.getRequestDispatcher("other.view?data=123456");
  22. // 请求包含
  23. // dispatcher.include(request, response);
  24. // 请求转发
  25. dispatcher.forward(request, response);
  26. out.println("Some do two...");
  27. }
  28. }

Some.java

  1. package com.test;
  2.  
  3. import javax.servlet.ServletException;
  4. import javax.servlet.annotation.WebServlet;
  5. import javax.servlet.http.HttpServlet;
  6. import javax.servlet.http.HttpServletRequest;
  7. import javax.servlet.http.HttpServletResponse;
  8. import java.io.IOException;
  9. import java.util.Arrays;
  10.  
  11. @WebServlet({"/other.view", "/view"})
  12. public class Other extends HttpServlet {
  13. @Override
  14. protected void doGet(HttpServletRequest request, HttpServletResponse response)
  15. throws ServletException, IOException {
  16.  
  17. String data = request.getParameter("data");
  18. int[] getAttr = (int[])request.getAttribute("setAttr");
  19.  
  20. response.getWriter().println("Other do one..." + " | "
  21. + "include or forward parameter: " + data + " | " // 请求或转发时携带的查询参数
  22. + "setAttrbute object: " + Arrays.toString(getAttr)); // 共享对象
  23. }
  24. }

Other.java

请求转发 forward 的响应结果是:

  Other do one... | include or forward parameter: 123456 | setAttrbute object: [1, 2, 3]

请求包含 include 的响应结果是:

  Some do one...
  Other do one... | include or forward parameter: 123456 | setAttrbute object: [1, 2, 3]
  Some do two...


相似点

javax.servlet.

include.request_uri

javax.servlet.

include.context_path

javax.servlet.

include.servlet_path

javax.servlet.

include.path_info

javax.servlet.

include.query_string

javax.servlet.

forward.request_uri

javax.servlet.

forward.context_path

javax.servlet.

forward.servlet_path

javax.servlet.

forward.path_info

javax.servlet.

forward.query_string

Servlet

Request URI Context path Servlet path Path info

取得RequestDispatcher时

给定的查询参数

如果被包含或转发的Servlet还包含或转发其他的Servlet,则这些属性名称的对应值也会被代换。

example:

  1. package com.test;
  2.  
  3. import javax.servlet.RequestDispatcher;
  4. import javax.servlet.ServletException;
  5. import javax.servlet.annotation.WebServlet;
  6. import javax.servlet.http.HttpServlet;
  7. import javax.servlet.http.HttpServletRequest;
  8. import javax.servlet.http.HttpServletResponse;
  9. import java.io.IOException;
  10. import java.io.PrintWriter;
  11.  
  12. @WebServlet({"/some.controller", "/world"})
  13. public class Some extends HttpServlet {
  14. @Override
  15. protected void doGet(HttpServletRequest request, HttpServletResponse response)
  16. throws ServletException, IOException {
  17. PrintWriter out = response.getWriter();
  18. out.println("Some do one...");
  19. RequestDispatcher dispatcher = request.getRequestDispatcher("other.view?data=123456");
  20. // 请求包含
  21. dispatcher.include(request, response);
  22. // 请求转发
  23. // dispatcher.forward(request, response);
  24. out.println("Some do two...");
  25. }
  26. }

Some.java

  1. package com.test;
  2.  
  3. import javax.servlet.ServletException;
  4. import javax.servlet.annotation.WebServlet;
  5. import javax.servlet.http.HttpServlet;
  6. import javax.servlet.http.HttpServletRequest;
  7. import javax.servlet.http.HttpServletResponse;
  8. import java.io.IOException;
  9.  
  10. @WebServlet({"/other.view", "/view"})
  11. public class Other extends HttpServlet {
  12. @Override
  13. protected void doGet(HttpServletRequest request, HttpServletResponse response)
  14. throws ServletException, IOException {
  15.  
  16. String request_uri, context_path, servlet_path, path_info, query_string;
  17.  
  18. // 默认的请求包含时的参数
  19. /*request_uri = (String)request.getAttribute("javax.servlet.include.request_uri");
  20. context_path = (String)request.getAttribute("javax.servlet.include.context_path");
  21. servlet_path = (String)request.getAttribute("javax.servlet.include.servlet_path");
  22. path_info = (String)request.getAttribute("javax.servlet.include.path_info");
  23. query_string = (String)request.getAttribute("javax.servlet.include.query_string");*/
  24. // 默认的请求转发时的参数
  25. request_uri = (String)request.getAttribute("javax.servlet.forward.request_uri");
  26. context_path = (String)request.getAttribute("javax.servlet.forward.context_path");
  27. servlet_path = (String)request.getAttribute("javax.servlet.forward.servlet_path");
  28. path_info = (String)request.getAttribute("javax.servlet.forward.path_info");
  29. query_string = (String)request.getAttribute("javax.servlet.forward.query_string");
  30.  
  31. response.getWriter().println("Other do one..." + " | "
  32. + "request_uri: " + request_uri + " | "
  33. + "context_path: " + context_path + " | "
  34. + "servlet_path: " + servlet_path + " | "
  35. + "path_info: " + path_info + " | "
  36. + "query_string: " + query_string
  37. );
  38. }
  39. }

Other.java

请求转发 forward 的响应结果是:

  Other do one... | request_uri: /hello/some.controller | context_path: /hello | servlet_path: /some.controller | path_info: null | query_string: null

请求包含 include 的响应结果是:

  Some do one...
  Other do one... | request_uri: /hello/other.view | context_path: /hello | servlet_path: /other.view | path_info: null | query_string: data=123456
  Some do two...

请求包含(Include)和请求转发(Forward)的更多相关文章

  1. 请求转发(forward)和请求包含(include)的区别?

    请求包含的例子 第一个Servlet (DispatcherServlet) @Override protected void doGet(HttpServletRequest req, HttpSe ...

  2. Java Web中请求转发和请求包含

    1.都是在一个请求中跨越多个Servlet 2.多个Servlet在一个请求中,他们共享request对象.就是在AServle中setAttribute()保存数据在BServlet中由getAtt ...

  3. 20160326 javaweb 请求转发和请求包含

    (1)请求转发: this.getServletContext().getRequestDispatcher("").forward(request,response); requ ...

  4. Web---字节输出流和字符输出流的共存问题、转发、重定向、请求包含知识点讲解

    本章博客的知识点: 1.字节输出流和字符输出流的共存问题 2.转发时,两个servlet都输出信息的问题 详细知识,见OneServlet和TwoServlet源代码中的注释 转发:传参,访问顺序(d ...

  5. ServletRequest HttpServletRequest 请求方法 获取请求参数 请求转发 请求包含 请求转发与重定向区别 获取请求头字段

      ServletRequest 基本概念 JavaWeb中的 "Request"对象  实际为   HttpServletRequest  或者  ServletRequest, ...

  6. getRequestDispatcher 中请求转发和请求包含的使用说明

    getRequestDispatcher() getRequestDispatcher() 包含两个方法,分别是请求转发和请求包含. RequestDispatcher rd = request.ge ...

  7. 直接请求转发(Forward)和间接请求转发(Redirect)两种区别?

    用户向服务器发送了一次HTTP请求,该请求肯能会经过多个信息资源处理以后才返回给用户,各个信息资源使用请求转发机制相互转发请求,但是用户是感觉不到请求转发的.根据转发方式的不同,可以区分为直接请求转发 ...

  8. 请求转发(forward)和请求重定向(redirect)的区别(转)

    作者:@haimishasha本文为作者原创,转载请注明出处:https://www.cnblogs.com/haimishasha/p/5952129.html 用户向服务器发送了一次HTTP请求, ...

  9. 请求转发(forward)和重定向(redirect)的区别

    转发不会改变地址栏,重定向会. 转发是请求一次,重定向请求两次. 转发过程中只有一个request对象产生,重定向是两个. 转发不能转发到站外,重定向可以发送到站外. 重定向的第2个请求的请求方式是什 ...

随机推荐

  1. easyui 中iframe嵌套页面,提示弹窗遮罩的解决方法,parent.$.messager.alert和parent.$.messager.confirm

    项目中用到easyui 布局,用到north,west,center三个区域,且在center中间区域嵌入iframe标签.在主内容区做一些小提示弹窗(例如删除前的弹窗提示确认)时,会遇到遮罩问题,由 ...

  2. 配置文件备份方案(expect+shell)

    需求描述:备份所有线上服务器squid.httpd.mysql.nginx的配置文件 环境:在公司内网采用expect+shell脚本模式,进行批量备份.expect脚本通过ssh登录服务器,从本地c ...

  3. (转)MySQL字段类型详解

    MySQL字段类型详解 原文:http://www.cnblogs.com/100thMountain/p/4692842.html MySQL支持大量的列类型,它可以被分为3类:数字类型.日期和时间 ...

  4. Linux-(diff)

    diff 命令 1.命令格式: diff  [参数]  [文件1或目录1]  [文件2或目录2] 2.命令功能: diff命令能比较单个文件或者目录内容.如果指定比较的是文件,则只有当输入为文本文件时 ...

  5. Windows下整合apache和Tomcat

    1.前言: 引用:http://www.cnblogs.com/liaokailin/p/3963603.html 引用的博客里面有比较详细的说明,并且结合图片,非常生动: 我这里只做简单的说明和整合 ...

  6. my97datePicker的相信使用

    http://www.my97.net/dp/demo/resource/2.1.asp

  7. JVM内存限制和调整

    今天用java -jar执行一个jar文件提示内存不够,需要设置虚拟机的堆大小.以下是参考资料: 堆(Heap)和非堆(Non-heap)内存  按照官方的说法:“Java 虚拟机具有一个堆,堆是运行 ...

  8. GDI+中发生一般性错误的解决办法(转)

    今天在开发.net引用程序中,需要System.Drawing.Image.Save 创建图片,debug的时候程序一切正常,可是发布到IIS后缺提示出现"GDI+中发生一般性错误" ...

  9. NPOI读取Excel官方demo

    关键代码: 读: HSSFWorkbook hssfworkbook; void InitializeWorkbook(string path) { //read the template via F ...

  10. C# 委托、匿名方法、扩展方法

    一.委托的使用: 详细委托和事件解释请看另一篇:http://www.cnblogs.com/Liyuting/p/6760706.html 二.匿名方法 三.扩展方法