转发请求
构建Web应用时,把请求转发给另一个servlet处理、或在response中包含另一个servlet的输出通常是很有用的。RequestDispatcher接口提供了一种机制来实现这种功能。
当请求启用异步处理时,AsyncContext允许用户将这个请求转发到servlet容器。
9.1 获得一个RequestDispatcher
实现了RequestDispatcher接口的对象,可以从ServletContext中的下面方法得到:
getRequestDispatcher
getNamedDispatcher
getRequestDispatcher方法需要一个String类型的参数描述在ServletContext作用域内的路径。这个路径必须是相对于ServletContext的根路径,或以’/’开头,或者为空。该方法根据这个路径使用servlet路径匹配规则(见第12章,请求映射到servlet)来查找servlet,把它包装成RequestDispatcher对象并返回。如果基于给定的路径没有找到相应的servlet,那么返回这个路径内容提供的RequestDispatcher。
getNamedDispatcher方法使用一个ServletContext知道的servlet名称作为参数。如果找到一个servlet,则把它包装成RequestDispatcher对象,并返回该对象。如果没有与给定名字相关的servlet,该方法必须返回null。
为了让RequestDispatcher对象使用相对于当前请求路径的相对路径(不是相对于ServletContext根路径)获得一个servlet,在ServletRequest接口中提供了getRequestDispatcher方法。
此方法的行为与ServletContext中同名的方法相似。Servlet容器根据request对象中的信息把给定的相对路径转换成当前servlet的完整路径。例如,在以’/’作为上下文根路径和请求路径/garden/tools.html中,通过ServletRequest.getRequestDispatcher("header.html")获得的请求调度器和通过调用ServletContext.getRequestDispatcher("/garden/header.html")获得的完全一样。
9.1.1 请求调度器路径中的查询字符串
ServletContext和ServletRequest中创建RequestDispatcher对象的方法使用的路径信息中允许附加可选的查询字符串信息。比如,开发人员可以通过下面的代码来获得一个RequestDispatcher:
String path = “/raisins.jsp?orderno=5”;
RequestDispatcher rd = context.getRequestDispatcher(path);
rd.include(request, response);
查询字符串中指定的用来创建RequestDispatcher的参数优先于传递给它包含的servlet中的其他同名参数。与RequestDispatcher相关的参数作用域仅适用于包含(include)或转发(forward)调用期间。
9.2 请求调度器的使用
要使用请求调度器,servlet可调用RequestDispatcher接口的include或forward方法。这些方法的参数既可以是javax.servlet.Servlet接口的service方法传来的request和response对象实例,也可以是本规范的2.3版本中介绍的request和response包装器类的子类对象实例。对于后者,包装器实例必须包装容器传递到service方法中的request和response对象。
容器提供者应该保证分发到目标servlet的请求作为原始请求发生在的同一个JVM的同一个线程中。
9.3 Include方法
RequestDispatcher接口的include方法可能随时被调用。Include方法的目标servlet能够访问request对象的各个方法(all aspects),但是使用response对象的方法会受到更多限制。
它只能把信息写到response对象的ServletOutputStream或Writer中,或提交在最后写保留在response缓冲区中的内容,或通过显式地调用ServletResponse接口的flushBuffer方法。它不能设置响应头部信息或调用任何影响响应头部信息的方法,HttpServletRequest.getSession()和HttpServletRequest.getSession(boolean)方法除外。任何试图设置头部信息必须被忽略,任何调用HttpServletRequest.getSession()和HttpServletRequest.getSession(boolean)方法将需要添加一个Cookie响应头部信息,如果响应已经提交,必须抛出一个IllegalStateException异常。
如果默认的servlet是RequestDispatch.include()的目标servlet,而且请求的资源不存在,那么默认的servlet必须抛出FileNotFoundException异常。如果这个异常没有被捕获和处理,以及响应还未提交,则响应状态码必须被设置为500。
9.3.1 内置请求参数
除了可以用getNamedDispatcher方法获得servlet外,已经被另一个servlet使用RequestDispatcher的include方法调用过的servlet,有权访问被调用过的servlet的路径。
以下的request属性必须被设置:
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
这些属性可以通过包含的servlet的request对象的getAttribute方法访问,它们的值必须分别与被包含servlet的请求RUI、上下文路径、servlet路径、路径信息、查询字符串相等。如果随后的请求包含这些属性,那么这些属性会被后面包含的属性值替换。
如果包含的servlet通过getNamedDispatcher方法获得,那么这些属性不能被设置。
9.4 Forward方法
RequestDispatcher接口的forward方法,只有在没有输出提交到向客户端时,通过正在被调用的servlet调用。如果response缓冲区中存在尚未提交的输出数据,这些数据内容必须在目标servlet的service方法调用前清除。如果response已经提交,必须抛出一个IllegalStateException异常。
request对象暴露给目标servlet的路径元素(path elements)必须反映获得RequestDispatcher使用的路径。
唯一例外的是,如果RequestDispatcher是通过getNamedDispatcher方法获得。这种情况下,request对象的路径元素必须反映这些原始请求。
在RequestDispatcher接口的forward方法无异常返回之前,响应的内容必须被发送和提交,且由Servlet容器关闭,除非请求处于异步模式。如果RequestDispatcher.forward()的目标发生错误,异常信息会传回所有调用它经过的过滤器和servlet,且最终传回给容器。
9.4.1 查询字符串
在转发或包含请求时请求调度机制负责聚集(aggregating)查询字符串参数。
9.4.2 转发的请求参数
除了可以用getNamedDispatcher方法获得servlet外,已经被另一个servlet使用RequestDispatcher的forward方法调用过的servlet,有权访问被调用过的servlet的路径。
以下的request属性必须设置:
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方法的返回值相等,这些方法在从客户端接收到的request对象上调用,值传递给调用链中的第一个servlet对象。
(在request对象上调用从客户端接收请求的调用链中的第一个servlet对象)
这些属性通过转发servlet的request对象的getAttribut方法访问。请注意,即使在多个转发和相继的包含(subsequent includes)被调用的情况下,这些属性必须始终反映原始请求中的信息。
如果转发的servlet使用getNamedDispatcher方法获得,这些属性必须不能被设置。
9.5 错误处理
如果请求分发的目标servlet抛出运行时异常或受检查类型异常ServletException 或 IOException,异常应该传播到调用的servlet。所有其它的异常都应该被包装成ServletExceptions,异常的根本原因设置成原来的异常,因为它不应该被传播。
9.6 获得一个异步上下文对象
实现了AsyncContext接口的对象可从ServletRequest的一个startAsync方法中获得,一旦有了AsyncContext对象,你就能够使用它的complete()方法来完成请求处理,或使用下面描述的转发方法。
9.7 Dispatch方法
可以使用AsyncContext中下面的方法来转发请求:
dispatch(path)
这个dispatch方法的String参数描述了一个在ServletContext作用域中的路径。这个路径必须是相对于ServletContext的根路径并以’/’开头。
dispatch(servletContext, path)
这个dispatch方法的String参数描述了一个在ServletContext指定作用域中的路径。这个路径必须是相对于ServletContext的根路径并以’/’开头。
dispatch()
这个方法没有参数,它使用原来的URI路径。如果AsyncContext已经通过startAsync(ServletRequest, ServletResponse)初始化,且传递过来的request是HttpServletRequest的实例,那么这个请求分发到HttpServletRequest.getRequestURI()返回的URI。否则当最后转发时当由容器转发到request的URI。
AsyncContext接口中的dispatch方法可被等待异步事件发生的应用程序调用。如果AsyncContext已经调用了complete()方法,必须抛出IllegalStateException异常。所有不同的dispatch方法会立即返回并且不会提交response。
request对象暴露给目标servlet的路径元素(path elements)必须反映AsyncContext.dispatch中指定的路径。
9.7.1 查询字符串
请求调度机制是在调度请求时负责聚焦(aggregating)查询字符串。
9.7.2 调度请求参数
使用AsyncContext的dispatch方法调用过的servlet能够访问原始请求的路径。
下面的request属性必须设置:
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方法的返回值相等,这些方法在从客户端接收到的request对象上调用,值传递给调用链中的第一个servlet对象。
这些属性通过转发servlet的request对象的getAttribut方法访问。请注意,即使在多个转发和相继的包含(subsequent includes)被调用的情况下,这些属性必须始终反映原始请求中的信息。
分享到:
相关推荐
Java Servlet 3.1 规范是Java Web开发中的一个重要里程碑,它定义了Servlet容器(如Tomcat、Jetty)与Web应用程序之间的交互标准。这个规范不仅提供了对HTTP协议的处理,还包括了对WebSocket、异步处理、依赖注入等...
Java Servlet 3.1规范,JSR 340,是Java Web开发中的核心标准,它定义了如何创建和管理动态Web内容。本规范详细阐述了servlet的概念、功能以及与之相关的servlet容器。 **1. 什么是servlet** Servlet是一种基于...
5. **Apache Tomcat 9**:作为Servlet容器,Tomcat 9支持Servlet 3.1规范,提供高性能、轻量级的部署环境,用于运行Spring MVC应用程序。 6. **MySQL**:MySQL是一种广泛使用的开源关系型数据库,与Spring JPA和...
Servlet 3.1是Servlet规范的最新版本,引入了注解配置、异步处理、微调部署、动态资源加载等功能,使得开发更加简洁和高效。 4. **章节分布**: - `ch1.pptx`可能涵盖Java EE的基础知识,包括环境搭建、Tomcat...
3. **servlet-3_1-final.pdf** 和 **Servlet3.1规范(最终版).pdf**:这两个文件都是Servlet 3.1版本的最终规范文档,该版本引入了诸如异步处理、注解配置、过滤器链等功能增强。 4. **servlet-2_3-fcs-spec.pdf**...
Tomcat 8.0是一个流行的开源JavaEE应用服务器,它实现了Servlet和JSP规范,是部署JavaEE应用的理想选择。本书中,所有源代码都需要在Tomcat环境下运行,读者可以借此机会学习如何配置和管理Tomcat服务器。 源代码...
6. **Servlet的转发与重定向**:Servlet可以使用`RequestDispatcher`的`forward()`方法将请求转发到其他资源,或者使用`response.sendRedirect()`方法进行重定向。 7. **Servlet容器**:Servlet运行在Servlet容器...
《JiveJdon——3.1:Java学习的宝贵资源》 在编程世界里,Java是一种广泛应用的编程语言,尤其在企业级应用开发领域占据着举足轻重的地位。"JiveJdon"是一个专为Java爱好者和学习者提供的论坛源代码,它为我们提供...
本文旨在深入剖析Struts框架的核心组件之一——`ActionServlet`的工作原理及其配置过程,帮助读者更好地理解Struts框架的内部机制。 #### 二、ActionServlet概述 `ActionServlet`是Struts框架中的关键组件,负责...
**SpringMVC 3.1 实例源码详解** SpringMVC是Spring框架的一个核心模块,专注于处理Web应用的请求和响应。在这个基于SpringMVC 3.1的实例中,我们将深入探讨其主要功能、架构和配置。Spring 3.1引入了一些重要的...
此外,SpringMVC 3.1还引入了ModelAndView对象的替代品——`Model`和`ViewResolver`,这使得模型和视图的分离更加清晰。开发者可以直接在处理器方法中添加模型属性,而无需创建ModelAndView对象。 在异常处理方面,...
### JSP核心技术——JSP引擎内幕 #### 一、JSP引擎的工作原理 JSP(Java Server Pages)是一种基于Java的服务器端脚本技术,它允许开发者将动态内容嵌入到HTML网页中。JSP的核心功能是通过JSP引擎来实现的。JSP...
此外,理解Servlet API和JSP规范也是必不可少的,例如Servlet 3.1及以上版本引入了注解配置,使部署和管理Servlet变得更加简单。 在开发过程中,还会涉及到Web应用程序的部署描述符(web.xml),这是一个XML文件,...
1. **Servlet 3.1支持**:Jetty 9.2.x系列全面支持Servlet 3.1规范,这包括异步处理、WebSocket API和更高效的请求处理。这使得开发者可以利用更多的现代Web功能,同时提高应用性能。 2. **WebSocket支持**:随着...
Servlet 3.1引入了异步处理能力,允许在后台线程处理请求,提高性能。同时,注解配置也得到增强,使得部署更加灵活。 2. **JSP 2.3**:JavaServer Pages(JSP)是创建动态网页的工具,JSP 2.3提供了EL(Expression ...
《Spring Web MVC框架详解——基于org.springframework.web.servlet-3.1.0.RELEASE.jar》 在Java Web开发领域,Spring框架无疑是最具影响力的框架之一,其中Spring Web MVC是其核心组件,专注于处理Web请求和响应。...
1. **支持Java Servlet 3.1和JSP 2.3规范**:9.0版本引入了对更高级别Servlet和JSP规范的支持,提供了更多的API和功能。 2. **NIO.2支持**:除了传统的BIO和NIO模型,Tomcat 9.0引入了对Java NIO.2 API的支持,...
- **根本原因**:在Servlet规范中,当请求被发送至服务器端时,如果`request.getCharacterEncoding()`返回`null`,则默认使用ISO-8859-1编码解析参数。然而,大多数浏览器在发送POST或GET请求时,并不会明确指定编码...
3.1 JSP与Servlet:JSP用于创建动态网页,将业务逻辑与展示分离;Servlet在服务器端处理请求,与数据库交互,控制业务流程。 3.2 文件操作:使用Java的IO流进行文件的读写操作,处理上传和下载功能。 3.3 PDF解析...
2. **Tomcat8**: Tomcat是Apache软件基金会的开源Servlet容器,版本8是其一个重要的版本,支持Java Servlet 3.1规范。 在Tomcat集群环境中,由于请求可能会被分发到不同的服务器节点,因此,session的同步和共享是...