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对象的 ServletContexServletRequest方法,允许在路径上附加查询字符串信息。例如,开发者可以通过使用以下代码获得一个RequestDispatcher

String path = “/raisins.jsp?orderno=5”;
RequestDispatcher rd = context.getRequestDispatcher(path);
rd.include(request, response);

用于创建RequestDispatcher的查询字符串中指定的参数优先于传递给所包含的Servlet的其他同名参数。与RequestDispatcher相关的参数只在includeforward调用期间适用。

参数优先级

请求调度器的使用

为了使用一个请求调度器,Servlet会调用RequestDispatcher接口的include方法或forward方法。这些方法的参数可以是通过javax.servlet.Servlet接口的服务方法传入的requestresponse参数,也可以是为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使用RequestDispatcherinclude方法调用的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使用RequestDispatcherforward方法调用的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方法getRequestURIgetContextPathgetServletPathgetPathInfogetQueryString的返回值,分别在传递给从客户端接收请求的调用链中第一个Servlet对象的请求对象上调用。

这些属性可以通过请求对象上的getAttribute方法从转发的servlet访问。请注意,这些属性必须始终反映原始请求中的信息,即使在调用多个转发和后续包含的情况下也是如此。

如果被转发的servlet是通过使用getNamedDispatcher方法获得的,这些属性必须不被设置。

错误的处理

如果作为请求分派器目标的Servlet抛出了一个运行时异常或一个ServletExceptionIOException类型的检查异常,它应该被传播给调用的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 方法的参数

通过使用AsyncContextdispatch方法调用的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方法getRequestURIgetContextPathgetServletPathgetPathInfogetQueryString的返回值,分别在传递给调用链中第一个接收客户端请求的Servlet对象的请求对象上调用。

这些属性可以通过请求对象上的getAttribute方法从被派遣的servlet访问。请注意,这些属性必须始终反映原始请求中的信息,即使是在调用多个调度的情况下。

Servlet规范之转发请求相关推荐

  1. 【JavaLearn】#(23)JSP相关语法、HTTP协议、Servlet介绍、Servlet生命周期、请求和响应、相对路径、转发和重定向

    1. JSP简单内容 1.1 JavaEE JavaEE 包含JSP JavaEE是一个开发分布式企业级应用的规范和标准.JavaEE包含之前学过的所有内容(JavaSE) 真正开发中,很少使用Jav ...

  2. 基于Servlet体系的HTTP请求代理转发Spring Boot组件

    背景概述 两个项目组原本都是各自负责两个产品线(产品A.产品B),由于公司业务的发展,目前需要将两个产品合并成一个大产品(功能整合,部分做取舍,最终产出产品C),前后端代码必然也需要整合,包括两个产品 ...

  3. servlet 规范_Tomcat原理解析(壹)— Servlet

    Tomcat 汤姆猫大家应该都不陌生,是我们Javaer都应该知道的内容,它是一个Web容器,是Java Web的基础,所以我们都应该了解了解其原理相关内容. 我们先从Servlet讲起: Servl ...

  4. Servlet规范总结

    Servlet接口 Servlet规范的核心接口即是Servlet接口,它是所有Servlet类必须实现的接口,在Java Servelt API中已经提供了两个抽象类方便开发者实现Servlet类, ...

  5. Servlet规范之安全

    Security 文章是对 JSR-000340 JavaTM Servlet 3.1 Final Release的Java™ Servlet规范的翻译,尚未校准 文章目录 Security 简介 声 ...

  6. Javaweb核心之servlet规范过滤器-----Filter

    2 Servlet规范中的过滤器-Filter 2.1 过滤器入门 2.1.1 过滤器概念及作用 过滤器--Filter,它是JavaWeb三大组件之一.另外两个是Servlet和Listener. ...

  7. Web容器(三):Servlet规范和Servlet容器

    本文参照:极客时间-<深入拆解 Tomcat & Jetty>-03_你应该知道的Servlet规范和Servlet容器 & 04_打造和运行一个Servlet Servl ...

  8. Spring boot转发请求

    转发请求 Forward 表示转发到一个地址 ThymeleafViewResolver Spring MVC的视图解析器 作用,根据视图名,得到视图对象 createView 创建视图对象 view ...

  9. ssm 转发请求_SSM框架碰到的问题

    什么时候用classpath: 这是开发时候的项目结构 这是打包发布后的项目结构 "classpath:"指WEB-INF/classes/这个目录.所有的class文件和资源文件 ...

最新文章

  1. 你想要的宏基因组-微生物组知识全在这(181101)
  2. GitHub上大热的Deep Photo终于有TensorFlow版了!
  3. Vue2.0 UI框架Element运用之DateTimePicker(el-date-picker)初始值及时间格式转化等细节问题
  4. 第十一章项目沟通管理重点--转载
  5. c++ stl队列初始化_创建一个向量,并将其像C ++ STL中的数组一样初始化
  6. Java主要处理哪些类型的异常_Java技术高效处理异常有哪些呢?
  7. 每日英语:Electronics Develop A Sixth Sense
  8. 订阅个人Blog最新评论的方法
  9. 第一章 Java代码执行流程
  10. b站的视频如何下载到手机上
  11. 三角波的傅里叶变换公式_南瓜老师的数学思维训练营 第14期 —— 三角恒等变换公式...
  12. 我心中有猛虎在细嗅蔷薇
  13. ChatGPT4.0中国怎么使用
  14. 无人驾驶汽车系统入门(二十六)——基于深度学习的实时激光雷达点云目标检测及ROS实现
  15. 记一次发现某餐饮企业二维码支付漏洞的经历
  16. Centos7 安装部署Kubernetes(k8s)集群过程
  17. Kibana:Kibana 入门 (二)
  18. echo “新密码“ | passwd --stdin 用户名
  19. Leetcode 1229. 安排会议日程
  20. 阿里云面试:什么是语法糖?Java中有哪些语法糖?

热门文章

  1. 全卷积网络FCN与卷积神经网络CNN的区别
  2. 题目 1224: 整除的尾数
  3. python读取文件夹中的图片
  4. Perl Regular Expression Syntax Perl的正则表达式语法
  5. cas单点登录学习笔记 .
  6. 单线激光雷达Windows测试备忘
  7. 【python爬虫】京东商品分析
  8. linux常用命令及通过浏览器访问linux文件功能
  9. 【Unity】Unity 2D游戏开发(一)U2D基础功能
  10. 数字平原CG场景搭建制作流程解析