Servlet 请求转发
目录
请求转发
RequestDispatcher 接口
请求转发的工作原理
请求转发的特点
request 域对象
示例
Web 应用在处理客户端的请求时,经常需要多个 Web 资源共同协作才能生成响应结果。但由于 Serlvet 对象无法直接调用其他 Servlet 的 service() 方法,所以 Servlet 规范提供了 2 种解决方案:
- 请求转发
- 请求包含(了解即可)
下面我们主要对请求转发进行介绍。
请求转发
请求转发属于服务器行为。容器接收请求后,Servlet 会先对请求做一些预处理,然后将请求传递给其他 Web 资源,来完成包括生成响应在内的后续工作。
RequestDispatcher 接口
javax.servlet 包中定义了一个 RequestDispatcher 接口,RequestDispatcher 对象由 Servlet 容器创建,用于封装由路径所标识的 Web 资源。利用 RequestDispatcher 对象可以把请求转发给其他的 Web 资源。
Servlet 可以通过 2 种方式获得 RequestDispatcher 对象:
- 调用 ServletContext 的 getRequestDispatcher(String path) 方法,参数 path 指定目标资源的路径,必须为绝对路径;
- 调用 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 资源进行处理。请求转发的工作原理如下图所示。
请求转发的特点
请求转发具有以下特点:
- 请求转发不支持跨域访问,只能跳转到当前应用中的资源。
- 请求转发之后,浏览器地址栏中的 URL 不会发生变化,因此浏览器不知道在服务器内部发生了转发行为,更无法得知转发的次数。
- 参与请求转发的 Web 资源之间共享同一 request 对象和 response 对象。
- 由于 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 请求转发相关推荐
- 解决servlet请求转发、响应重定向无法实现页面跳转问题
问题:login.html能正常运行,但当用户名和密码正确后,点击登录按钮,通过html页面的action属性值和servlet页面的urlPatterns属性值,实现servlet请求转发,无法实现 ...
- Servlet 请求转发(forword)与重定向(sendredirect)的区别
servlet请求转发与重定向的区别: request.setAttribute("test","hello"); request.getRequestDisp ...
- Servlet请求转发中文乱码解决
2019独角兽企业重金招聘Python工程师标准>>> 在Servlet的使用过程中,如果在请求转发的同时需要获得输出流并且写出数据的时候,需要设定resp 的编码格式,否则的话,跳 ...
- httpservletresponse 重定向浏览器不变的原因_JavaWeb——Servlet——请求转发与响应重定向...
导语:在实际的软件开发过程中,往往需要多个Servlet来实现不同的功能,就需要对多个Servlet进行组合调用.多个Servlet之间如何进行通信和跳转?而这就需要用到请求转发与响应重定向技术. 原 ...
- servlet请求转发
来源:http://www.2cto.com/kf/201610/554591.html 请求转发:Servlet(源组件)先对客户请求做一些预处理操作(数据处理),然后把请求转发给其他Web组件(目 ...
- servlet中请求转发(forword)与重定向(sendredirect)的区别
servlet请求转发与重定向的区别: request.setAttribute("test","hello"); request.getRequestDisp ...
- Servlet--06--解决乱码问题; 请求转发; 重定向;
乱码问题: 一. 请求-乱码问题:服务器获取的请求数据,在console显示时,出现了乱码. (1)post请求方式解决:req.serCharacterEncoding("utf-8&q ...
- 详解请求转发和重定向
** 详解请求转发和重定向 **servlet请求转发与重定向的区别: request.setAttribute("test","hello"); reques ...
- JAVA记录-Servlet RequestDispatcher请求转发
RequestDispatcher接口提供将请求转发送到另一个资源的功能,它可能是html,servlet或jsp等. 此接口也可用于包括另一资源的内容.它是servlet协作的一种方式. 在Requ ...
- 【Servlet】请求转发、重定向、Cookie使用之三天自动登陆
三天自动登陆项目源码:GitHub地址-LoginSystem JDBC 手写SORM框架 手写Servlet 开发环境:Eclipse 一.请求乱码问题解决 // 设置请求.响应编码格式req.se ...
最新文章
- 在 Delphi 下使用 DirectSound (5): 获取或设置缓冲区的格式:
- 如何在不使用任何图像或跨度标签的情况下通过CSS在UL / LI html列表中设置子弹颜色[复制]
- 获得 bootstrapTable行号index
- Android studio如何写滚动视图
- 用shell脚本一键搭建LNMP环境实战
- GIS开发平台的未来 — .NET还是J2EE?
- error: libXpm.(a|so)
- Tomcat5的数据库连接池配置
- 执行计划有时不准确_一张表格,帮助学生制定良好每日学习计划,提升学习积极性主动性...
- 华为模拟器ENSP下载与安装详细教程(win10 LTSC系统中安装)
- CRM实战分类以及对企业运营的思考
- 高性能计算中的并行计算、分布式计算、网格计算和云计算之间的区别与联系
- 企业微信——定时群机器人布置
- 淘宝开通恶意评价维权通道 客服24小时内处理
- GDAL ogr2ogr 转换mif 为sqlite
- 単語ーー下げる(さげる)
- 伸手摘星,未必如愿,但不会弄脏你的手……
- 正则表达式 (js)
- 传输加载优化(资源压缩、资源缓存、HTTP2)
- 维修服务行业薪酬体系设计案例
热门文章
- c语言程序中不能表示数制的是,2017计算机c语言二级考试题库及答案
- 使用burp对Tomcat 弱密码爆破
- 如何用Java和Kotlin实现高性能桌面条形码扫描
- php网页象棋源码,JS小游戏之象棋暗棋源码详解_javascript技巧
- ios safari 模拟器_电脑也能运行iOS iOS模拟器体验
- java项目 ppt,Java项目报告ppt
- 移动机械硬盘测试软件,硬盘检测工具HDTune使用教程
- 基于Java毕业设计幼儿园教育管理信息系统演示2021源码+系统+mysql+lw文档+部署软件
- 链表在java中的应用_Java链表
- Oracle项目管理系统之质量控制