Servlet规范之转发请求
Dispatching Requests
文章是对 JSR-000340 JavaTM Servlet 3.1 Final Release的Java™ Servlet规范的翻译,尚未校准
文章目录
- Dispatching Requests
- @[toc]
- 获取RequestDispatcher
- 请求调度器路径中的查询字符串
- 请求调度器的使用
- Include method
- Include方法的参数
- Forward Method
- 查询字符串
- Forward方法的参数
- 错误的处理
- 获取 AsyncContext
- Dispatch Method
- 查询字符串
- Dispatch 方法的参数
将RequestDispatcher理解为请求分配或调度器,实现请求的转发功能。
当建立一个Web应用程序时,将一个请求的处理转发给另一个servlet,或者将另一个servlet的输出包含在响应中,往往是有用的。RequestDispatcher
接口提供了一种机制来实现这一点。
当请求的异步处理被启用时,AsyncContext
允许用户将请求分派回Servlet容器。
获取RequestDispatcher
一个实现RequestDispatcher
接口的对象可以通过以下方法从ServletContext
获得:
getRequestDispatcher
getNamedDispatcher
getRequestDispatcher
方法需要一个String
参数,描述ServletContext范围内的一个路径。这个路径必须是相对于ServletContext
的根部,以"/"开头,或者是空的。该方法使用该路径查找一个Servlet,使用第12章 "Mapping Requests to Servlets"中的Servlet路径匹配规则,用一个RequestDispatcher
对象来包装它,并返回结果对象。如果不能根据给定的路径解析servlet,则提供一个RequestDispatcher
,返回该路径的内容。
getNamedDispatcher
方法接受一个字符串参数,表示ServletContext
已知的Servlet名称。如果找到一个servlet,它将被包裹在一个RequestDispatcher
对象中,并返回该对象。如果没有servlet与给定的名称相关联,该方法必须返回null。
为了允许使用相对于当前请求的路径(而不是相对于ServletContext
的根)获得RequestDispatcher
对象,在ServletRequest
接口中提供了getRequestDispatcher
方法。
这个方法的行为与ServletContext
中的同名方法类似。Servlet容器使用请求对象中的信息,将针对当前Servlet的给定相对路径转换为完整路径。例如,在一个根植于’/'的上下文和一个对/garden/tools.html
的请求中,通过ServletRequest.getRequestDispatcher("header.html")
获得的请求调度器的行为与调用ServletContext.getRequestDispatcher("/garden/header.html")
完全一样。
请求调度器路径中的查询字符串
使用路径信息创建RequestDispatcher
对象的 ServletContex
和 ServletRequest
方法,允许在路径上附加查询字符串信息。例如,开发者可以通过使用以下代码获得一个RequestDispatcher
。
String path = “/raisins.jsp?orderno=5”;
RequestDispatcher rd = context.getRequestDispatcher(path);
rd.include(request, response);
用于创建RequestDispatcher
的查询字符串中指定的参数优先于传递给所包含的Servlet的其他同名参数。与RequestDispatcher
相关的参数只在include
或forward
调用期间适用。
参数优先级
请求调度器的使用
为了使用一个请求调度器,Servlet会调用RequestDispatcher
接口的include方法或forward方法。这些方法的参数可以是通过javax.servlet.Servlet
接口的服务方法传入的request
和response
参数,也可以是为2.3版规范引入的请求和响应包装器类的子类实例。在后一种情况下,包装器实例必须包装容器传递到 service
方法中的请求或响应对象。
容器提供者应确保将请求分派给目标Servlet的过程与原始请求发生在同一JVM的同一线程中。
Include method
RequestDispatcher
接口的include
方法可以在任何时候被调用。包含方法的目标Servlet可以访问请求对象的所有方面,但它对响应对象的使用是比较有限的。
它只能将信息写入响应对象的ServletOutputStream
或Writer,并通过写入超过响应缓冲区末端的内容,或明确调用ServletResponse
接口的flushBuffer
方法来提交响应。除了HttpServletRequest.getSession()
和HttpServletRequest.getSession(boolean)
方法外,它不能设置头信息或调用任何影响响应头信息的方法。
任何试图设置头信息的行为都必须被忽略,如果响应已经被提交的情况下,任何对HttpServletRequest.getSession()
或HttpServletRequest.getSession(boolean)
的调用来实现添加Cookie响应头时,必须抛出IllegalStateException
。
如果默认Servlet是RequestDispatch.include()
的目标,并且请求的资源不存在,那么默认Servlet必须抛出FileNotFoundException
。如果这个异常没有被捕获和处理,而且响应还没有被提交,那么状态代码必须被设置为500。
Include方法的参数
除了通过使用getNamedDispatcher
方法获得的Servlet,被另一个Servlet使用RequestDispatcher
的include
方法调用的Servlet可以访问它被调用的路径。
以下请求属性必须被设置:
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
这些属性可以通过请求对象上的getAttribute
方法从被包含的servlet中访问,它们的值必须分别等于请求URI、上下文路径、servlet路径、路径信息和被包含servlet的查询字符串。如果该请求随后被包含,这些属性将被替换为该包含。
如果包含的servlet是通过使用getNamedDispatcher
方法获得的,这些属性必须不被设置。
Forward Method
RequestDispatcher
接口的forward
方法只有在没有向客户端提交输出的情况下才可以被调用的servlet调用。如果响应缓冲区中存在尚未提交的输出数据,必须在调用目标servlet的service
方法之前清除这些内容。如果响应已经被提交,必须抛出一个 “非法状态异常”(IllegalStateException
)。
暴露给目标Servlet的请求对象的路径元素必须反映用于获取RequestDispatcher
的路径。
唯一的例外是如果RequestDispatcher
是通过getNamedDispatcher
方法获得的。在这种情况下,请求对象的路径元素必须反映原始请求的元素。
在RequestDispatcher
接口的forward
方法毫无例外地返回之前,响应内容必须被发送和提交,并由servlet容器关闭,除非该请求被放入异步模式。如果在RequestDispatcher.forward()
的目标中发生错误,该异常可能会通过所有调用的过滤器和servlet传播回来,最终回到容器中。
查询字符串
请求调度机制负责在转发或包括请求时汇总查询字符串参数。
Forward方法的参数
除了通过使用getNamedDispatcher
方法获得的Servlet,被另一个Servlet使用RequestDispatcher
的forward
方法调用的Servlet可以访问原始请求的路径。
以下请求属性必须被设置:
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
这些属性的值必须等于HttpServletRequest
方法getRequestURI
、getContextPath
、getServletPath
、getPathInfo
、getQueryString
的返回值,分别在传递给从客户端接收请求的调用链中第一个Servlet对象的请求对象上调用。
这些属性可以通过请求对象上的getAttribute
方法从转发的servlet访问。请注意,这些属性必须始终反映原始请求中的信息,即使在调用多个转发和后续包含的情况下也是如此。
如果被转发的servlet是通过使用getNamedDispatcher
方法获得的,这些属性必须不被设置。
错误的处理
如果作为请求分派器目标的Servlet抛出了一个运行时异常或一个ServletException
或IOException
类型的检查异常,它应该被传播给调用的Servlet。所有其他的异常都应该被包装成ServletExceptions
,并将异常的根本原因设置为原始异常,因为它不应该被传播。
获取 AsyncContext
一个实现AsyncContext
接口的对象可以通过startAsync
方法从ServletRequest
中获得。一旦你有了AsyncContext
,你可以用它通过complete()方法完成请求的处理,或者使用下面描述的一个调度方法。
Dispatch Method
以下方法可用于从AsyncContext
调度请求。
dispatch(path)
dispatch
方法接受一个字符串参数,描述ServletContext
范围内的一个路径。这个路径必须是相对于 ServletContext
的根,并且以"/"开头。
dispatch(servletContext, path)
dispatch
方法需要一个字符串参数,描述指定的ServletContext
范围内的路径。这个路径必须是相对于指定的 ServletContext
的根,并且以"/"开头。
dispatch()
dispatch
方法不需要参数。它使用原始URI作为路径。如果AsyncContext
是通过startAsync(ServletRequest, ServletResponse)
初始化的,并且传递的请求是HttpServletRequest
的实例,那么分派到HttpServletRequest.getRequestURI()
返回的URI。否则,派发到请求的URI,当它最后被容器派发时。
AsyncContext
接口的一个调度方法可以被等待异步事件发生的应用程序调用。如果在AsyncContext
上调用了complete(),必须抛出IllegalStateException
。所有调度方法的变化都会立即返回,并且不提交响应。
暴露给目标Servlet的请求对象的路径元素必须反映在AsyncContext.dispatch
中指定的路径。
查询字符串
请求调度机制负责在调度请求时汇总查询字符串参数。
Dispatch 方法的参数
通过使用AsyncContext
的dispatch
方法调用的servlet可以访问原始请求的路径。
以下请求属性必须被设置:
javax.servlet.async.request_uri
javax.servlet.async.context_path
javax.servlet.async.servlet_path
javax.servlet.async.path_info
javax.servlet.async.query_string
这些属性的值必须等于HttpServletRequest
方法getRequestURI
、getContextPath
、getServletPath
、getPathInfo
、getQueryString
的返回值,分别在传递给调用链中第一个接收客户端请求的Servlet对象的请求对象上调用。
这些属性可以通过请求对象上的getAttribute
方法从被派遣的servlet访问。请注意,这些属性必须始终反映原始请求中的信息,即使是在调用多个调度的情况下。
Servlet规范之转发请求相关推荐
- 【JavaLearn】#(23)JSP相关语法、HTTP协议、Servlet介绍、Servlet生命周期、请求和响应、相对路径、转发和重定向
1. JSP简单内容 1.1 JavaEE JavaEE 包含JSP JavaEE是一个开发分布式企业级应用的规范和标准.JavaEE包含之前学过的所有内容(JavaSE) 真正开发中,很少使用Jav ...
- 基于Servlet体系的HTTP请求代理转发Spring Boot组件
背景概述 两个项目组原本都是各自负责两个产品线(产品A.产品B),由于公司业务的发展,目前需要将两个产品合并成一个大产品(功能整合,部分做取舍,最终产出产品C),前后端代码必然也需要整合,包括两个产品 ...
- servlet 规范_Tomcat原理解析(壹)— Servlet
Tomcat 汤姆猫大家应该都不陌生,是我们Javaer都应该知道的内容,它是一个Web容器,是Java Web的基础,所以我们都应该了解了解其原理相关内容. 我们先从Servlet讲起: Servl ...
- Servlet规范总结
Servlet接口 Servlet规范的核心接口即是Servlet接口,它是所有Servlet类必须实现的接口,在Java Servelt API中已经提供了两个抽象类方便开发者实现Servlet类, ...
- Servlet规范之安全
Security 文章是对 JSR-000340 JavaTM Servlet 3.1 Final Release的Java™ Servlet规范的翻译,尚未校准 文章目录 Security 简介 声 ...
- Javaweb核心之servlet规范过滤器-----Filter
2 Servlet规范中的过滤器-Filter 2.1 过滤器入门 2.1.1 过滤器概念及作用 过滤器--Filter,它是JavaWeb三大组件之一.另外两个是Servlet和Listener. ...
- Web容器(三):Servlet规范和Servlet容器
本文参照:极客时间-<深入拆解 Tomcat & Jetty>-03_你应该知道的Servlet规范和Servlet容器 & 04_打造和运行一个Servlet Servl ...
- Spring boot转发请求
转发请求 Forward 表示转发到一个地址 ThymeleafViewResolver Spring MVC的视图解析器 作用,根据视图名,得到视图对象 createView 创建视图对象 view ...
- ssm 转发请求_SSM框架碰到的问题
什么时候用classpath: 这是开发时候的项目结构 这是打包发布后的项目结构 "classpath:"指WEB-INF/classes/这个目录.所有的class文件和资源文件 ...
最新文章
- 你想要的宏基因组-微生物组知识全在这(181101)
- GitHub上大热的Deep Photo终于有TensorFlow版了!
- Vue2.0 UI框架Element运用之DateTimePicker(el-date-picker)初始值及时间格式转化等细节问题
- 第十一章项目沟通管理重点--转载
- c++ stl队列初始化_创建一个向量,并将其像C ++ STL中的数组一样初始化
- Java主要处理哪些类型的异常_Java技术高效处理异常有哪些呢?
- 每日英语:Electronics Develop A Sixth Sense
- 订阅个人Blog最新评论的方法
- 第一章 Java代码执行流程
- b站的视频如何下载到手机上
- 三角波的傅里叶变换公式_南瓜老师的数学思维训练营 第14期 —— 三角恒等变换公式...
- 我心中有猛虎在细嗅蔷薇
- ChatGPT4.0中国怎么使用
- 无人驾驶汽车系统入门(二十六)——基于深度学习的实时激光雷达点云目标检测及ROS实现
- 记一次发现某餐饮企业二维码支付漏洞的经历
- Centos7 安装部署Kubernetes(k8s)集群过程
- Kibana:Kibana 入门 (二)
- echo “新密码“ | passwd --stdin 用户名
- Leetcode 1229. 安排会议日程
- 阿里云面试:什么是语法糖?Java中有哪些语法糖?