目录

请求转发

RequestDispatcher 接口

请求转发的工作原理

请求转发的特点

request 域对象

示例


Web 应用在处理客户端的请求时,经常需要多个 Web 资源共同协作才能生成响应结果。但由于 Serlvet 对象无法直接调用其他 Servlet 的 service() 方法,所以 Servlet 规范提供了 2 种解决方案:

  1. 请求转发
  2. 请求包含(了解即可)

下面我们主要对请求转发进行介绍。

请求转发

请求转发属于服务器行为。容器接收请求后,Servlet 会先对请求做一些预处理,然后将请求传递给其他 Web 资源,来完成包括生成响应在内的后续工作。

RequestDispatcher 接口

javax.servlet 包中定义了一个 RequestDispatcher 接口,RequestDispatcher 对象由 Servlet 容器创建,用于封装由路径所标识的 Web 资源。利用 RequestDispatcher 对象可以把请求转发给其他的 Web 资源。

Servlet 可以通过 2 种方式获得 RequestDispatcher 对象:

  1. 调用 ServletContext 的 getRequestDispatcher(String path) 方法,参数 path 指定目标资源的路径,必须为绝对路径;
  2. 调用 ServletRequest 的 getRequestDispatcher(String path) 方法,参数 path 指定目标资源的路径,可以为绝对路径,也可以为相对路径。

绝对路径是指以符号“/”开头的路径,“/”表示当前 Web 应用的根目录。相对路径是指相对当前 Web 资源的路径,不以符号“/”开头。

RequestDispatcher 接口中提供了以下方法。

返回值类型 方法 功能描述
void forward(ServletRequest request,ServletResponse response)  用于将请求转发给另一个 Web 资源。该方法必须在响应提交给客户端之前被调用,否则将抛出 IllegalStateException 异常
 void include(ServletRequest request,ServletResponse response)  用于将其他的资源作为当前响应内容包含进来

请求转发的工作原理

在 Servlet 中,通常使用 forward() 方法将当前请求转发给其他的 Web 资源进行处理。请求转发的工作原理如下图所示。

请求转发的特点

请求转发具有以下特点:

  1. 请求转发不支持跨域访问,只能跳转到当前应用中的资源。
  2. 请求转发之后,浏览器地址栏中的 URL 不会发生变化,因此浏览器不知道在服务器内部发生了转发行为,更无法得知转发的次数。
  3. 参与请求转发的 Web 资源之间共享同一 request 对象和 response 对象。
  4. 由于 forward() 方法会先清空 response 缓冲区,因此只有转发到最后一个 Web 资源时,生成的响应才会被发送到客户端。//串行同步

request 域对象

request 是 Servlet 的三大域对象(HttpServletRequest、HttpSession、ServletContext)之一,它需要与请求转发配合使用,才可以实现动态资源间的数据传递。

在 ServletRequest 接口中定义了一系列操作属性的方法,如下表。

返回值类型 方法 描述
void setAttribute(String name, Object o) 将 Java 对象与属性名绑定,并将它作为一个属性存放到 request 对象中。参数 name 为属性名,参数 object 为属性值。
Object getAttribute(String name) 根据属性名 name,返回 request 中对应的属性值。
void removeAttribute(String name) 用于移除 request 对象中指定的属性。
Enumeration getAttributeNames() 用于返回 request 对象中的所有属性名的枚举集合。 

Context 域对象和 request 域对象对比,具有以下 4 点差异:

1) 生命周期不同

  • Context 域对象的生命周期从容器启动开始,到容器关闭或者 Web 应用被移除时结束;
  • request 域对象的生命周期从客户端向容器发送请求开始,到对这次请求做出响应后结束。

2) 作用域不同

  • Context 域对象对整个 Web 应用内的所有Servlet都有效;
  • request 域对象只对本次请求涉及的 Servlet 有效。

3) Web 应用中数量不同

  • 整个 Web 应用中只有一个 Context 域对象;
  • 由于 Servlet 能处理多个请求,因此 Web 应用中的每个 Servlet 实例都可以有多个 request 域对象。

4) 实现数据共享的方式不同

  • Context 域对象可以独立完成动态资源之间的数据共享;
  • Request 域对象需要与请求转发配合使用才能实现动态资源之间的数据共享。

示例

下面我们通过一个案例加深大家对转发和 request 域对象的理解。创建一个名为 DispatcherServlet 的类,代码如下。

@WebServlet("/DispatcherServlet")
public class DispatcherServlet extends HttpServlet {private static final long serialVersionUID = 1L;protected void doGet(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {// 设置向页面输出内容格式response.setContentType("text/html;charset=UTF-8");PrintWriter writer = response.getWriter();// 尝试在请求转发前向response缓冲区写入内容,最后在页面查看是否展示writer.write("<h1>这是转发前在响应信息内的内容!</h1>");// 向reuqest域对象中添加属性,传递给下一个web资源request.setAttribute("webName", "CSDN博客");request.setAttribute("url", "www.csdn.net");request.setAttribute("welcome", "welcome to DispatcherServlet");// 转发request.getRequestDispatcher("/DoServlet").forward(request, response);}protected void doPost(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {doGet(request, response);}
}

然后,再创建一个名称为 DoServlet 的类,代码如下。

@WebServlet("/DoServlet")
public class DoServlet extends HttpServlet {private static final long serialVersionUID = 1L;protected void doGet(HttpServletRequest request, HttpServletResponse response)throws IOException {//修改request缓冲区的字符集为UTF-8request.setCharacterEncoding("utf-8");// 设置向页面输出内容格式response.setContentType("text/html;charset=UTF-8");PrintWriter writer = response.getWriter();String webName = (String) request.getAttribute("webName");String url = (String) request.getAttribute("url");String welcome = (String) request.getAttribute("welcome");if (webName != null) {writer.write("<h3>" + webName + "</h3>");}if (url != null) {writer.write("<h3>" + url + "</h3>");}if (welcome != null) {writer.write("<h3>" + welcome + "</h3>");}String username = request.getParameter("username");// 获取密码String password = request.getParameter("password");// 获取性别String sex = request.getParameter("sex");// 获取城市String city = request.getParameter("city");// 获取使用语言返回是String数组String[] languages = request.getParameterValues("language");writer.write("用户名:" + username + "<br/>" + "密码:" + password + "<br/>" + "性别:" + sex + "<br/>" + "城市:" + city+ "<br/>" + "使用过的语言:" + Arrays.toString(languages) + "<br/>");}protected void doPost(HttpServletRequest request, HttpServletResponse response)throws IOException {doGet(request, response);}
}

在 webapp 根目录下,创建 web_form.html,代码如下。

<!DOCTYPE html>
<html>
<head><meta charset="UTF-8"><title>Insert title here</title>
</head>
<body>
<form action="/web/DispatcherServlet" method="post"><table border="1" width="50%"><tr><td colspan="2" align="center">welcome to RequestForm!</td></tr><tr><td>输入姓名</td><td><input type="text" name="username" /></td></tr><tr><td>输入密码</td><td><input type="password" name="password" /></td></tr><tr><td>选择性别</td><td><input type="radio" name="sex" value="male" />男 <inputtype="radio" name="sex" value="female" />女</td></tr><tr><td>选择使用的语言</td><td><input type="checkbox" name="language" value="JAVA" />JAVA<input type="checkbox" name="language" value="C" />C语言 <inputtype="checkbox" name="language" value="PHP" />PHP <inputtype="checkbox" name="language" value="Python" />Python</td></tr><tr><td>选择城市</td><td><select name="city"><option value="none">--请选择--</option><option value="beijing">北京</option><option value="shanghai">上海</option><option value="guangzhou">广州</option></select></td></tr><tr><td colspan="2"><input type="submit" value="提交" /></td></tr></table>
</form>
</body>
</html>

启动 Tomcat 服务器,在地址栏输入“http://localhost:8080/web/web_form.html”,访问 web_form.html,结果如下图。

填写表单信息,点击提交,结果如下图。

Servlet 请求转发相关推荐

  1. 解决servlet请求转发、响应重定向无法实现页面跳转问题

    问题:login.html能正常运行,但当用户名和密码正确后,点击登录按钮,通过html页面的action属性值和servlet页面的urlPatterns属性值,实现servlet请求转发,无法实现 ...

  2. Servlet 请求转发(forword)与重定向(sendredirect)的区别

    servlet请求转发与重定向的区别: request.setAttribute("test","hello"); request.getRequestDisp ...

  3. Servlet请求转发中文乱码解决

    2019独角兽企业重金招聘Python工程师标准>>> 在Servlet的使用过程中,如果在请求转发的同时需要获得输出流并且写出数据的时候,需要设定resp 的编码格式,否则的话,跳 ...

  4. httpservletresponse 重定向浏览器不变的原因_JavaWeb——Servlet——请求转发与响应重定向...

    导语:在实际的软件开发过程中,往往需要多个Servlet来实现不同的功能,就需要对多个Servlet进行组合调用.多个Servlet之间如何进行通信和跳转?而这就需要用到请求转发与响应重定向技术. 原 ...

  5. servlet请求转发

    来源:http://www.2cto.com/kf/201610/554591.html 请求转发:Servlet(源组件)先对客户请求做一些预处理操作(数据处理),然后把请求转发给其他Web组件(目 ...

  6. servlet中请求转发(forword)与重定向(sendredirect)的区别

    servlet请求转发与重定向的区别: request.setAttribute("test","hello"); request.getRequestDisp ...

  7. Servlet--06--解决乱码问题; 请求转发; 重定向;

    乱码问题: 一.  请求-乱码问题:服务器获取的请求数据,在console显示时,出现了乱码. (1)post请求方式解决:req.serCharacterEncoding("utf-8&q ...

  8. 详解请求转发和重定向

    ** 详解请求转发和重定向 **servlet请求转发与重定向的区别: request.setAttribute("test","hello"); reques ...

  9. JAVA记录-Servlet RequestDispatcher请求转发

    RequestDispatcher接口提供将请求转发送到另一个资源的功能,它可能是html,servlet或jsp等. 此接口也可用于包括另一资源的内容.它是servlet协作的一种方式. 在Requ ...

  10. 【Servlet】请求转发、重定向、Cookie使用之三天自动登陆

    三天自动登陆项目源码:GitHub地址-LoginSystem JDBC 手写SORM框架 手写Servlet 开发环境:Eclipse 一.请求乱码问题解决 // 设置请求.响应编码格式req.se ...

最新文章

  1. 在 Delphi 下使用 DirectSound (5): 获取或设置缓冲区的格式:
  2. 如何在不使用任何图像或跨度标签的情况下通过CSS在UL / LI html列表中设置子弹颜色[复制]
  3. 获得 bootstrapTable行号index
  4. Android studio如何写滚动视图
  5. 用shell脚本一键搭建LNMP环境实战
  6. GIS开发平台的未来 — .NET还是J2EE?
  7. error: libXpm.(a|so)
  8. Tomcat5的数据库连接池配置
  9. 执行计划有时不准确_一张表格,帮助学生制定良好每日学习计划,提升学习积极性主动性...
  10. 华为模拟器ENSP下载与安装详细教程(win10 LTSC系统中安装)
  11. CRM实战分类以及对企业运营的思考
  12. 高性能计算中的并行计算、分布式计算、网格计算和云计算之间的区别与联系
  13. 企业微信——定时群机器人布置
  14. 淘宝开通恶意评价维权通道 客服24小时内处理
  15. GDAL ogr2ogr 转换mif 为sqlite
  16. 単語ーー下げる(さげる)
  17. 伸手摘星,未必如愿,但不会弄脏你的手……
  18. 正则表达式 (js)
  19. 传输加载优化(资源压缩、资源缓存、HTTP2)
  20. 维修服务行业薪酬体系设计案例

热门文章

  1. c语言程序中不能表示数制的是,2017计算机c语言二级考试题库及答案
  2. 使用burp对Tomcat 弱密码爆破
  3. 如何用Java和Kotlin实现高性能桌面条形码扫描
  4. php网页象棋源码,JS小游戏之象棋暗棋源码详解_javascript技巧
  5. ios safari 模拟器_电脑也能运行iOS iOS模拟器体验
  6. java项目 ppt,Java项目报告ppt
  7. 移动机械硬盘测试软件,硬盘检测工具HDTune使用教程
  8. 基于Java毕业设计幼儿园教育管理信息系统演示2021源码+系统+mysql+lw文档+部署软件
  9. 链表在java中的应用_Java链表
  10. Oracle项目管理系统之质量控制