1.RequestDispatcher
RequestDispatcher对象可以通过ServletContext对象的getRequestDispatcher方法获取,如下。
public abstract RequestDispatcher getRequestDispatcher(String paramString);
public abstract RequestDispatcher getNamedDispatcher(String paramString);
关于RequestDispatcher的源代码(源代码反编译自apache-tomcat-6.0.16下的servlet-api.jar)如下所示:
package javax.servlet;
import java.io.IOException;
public abstract interface RequestDispatcher
{
public abstract void forward(ServletRequest paramServletRequest, ServletResponse paramServletResponse)
throws javax.servlet.ServletException, IOException;
public abstract void include(ServletRequest paramServletRequest, ServletResponse paramServletResponse)
throws javax.servlet.ServletException, IOException;
}
1.1 include
include方法的使用示例如下:
package org.it315.ch5.inc;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class IncludingServlet extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=gb2312");
// response.setContentType("text/html;charset=iso8859-1");
PrintWriter out = response.getWriter();
String china = "中国";
out.println("china:" + china + "<br>");
RequestDispatcher rd = getServletContext().getRequestDispatcher(
"/IncludedServlet?p1=" + china);
out.println("start including:" + "<br>");
rd.include(request, response);
out.println("end including" + "<br>");
}
}
被引入(include)的servlet代码如下:
package org.it315.ch5.inc;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class IncludedServlet extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
// response.setContentType("text/html;charset=GB2312");
// response.setContentType("text/html;charset=iso8859-1");
// response.setCharacterEncoding("GB2312");
// response.setCharacterEncoding("iso8859-1");
response.setContentType("text/html;charset=GB2312");//由于被IncludingServlet所include,所以不在起作用
PrintWriter out = response.getWriter();
out.println("中国" + "<br>");
out.println("URI:(这里的request应该是调用者的request)" + request.getRequestURI()
+ "<br>");
out.println("QueryString(**注意这里**):" + request.getQueryString()
+ "<br>");
out.println("parameter p1:" + request.getParameter("p1") + "<br>");
}
}
对于的web.xml配置如下:
<!-- begin -->
<servlet>
<servlet-name>IncludedServlet</servlet-name>
<servlet-class>org.it315.ch5.inc.IncludedServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>IncludedServlet</servlet-name>
<url-pattern>/ch5/IncludedServlet</url-pattern>
</servlet-mapping>
<!--end -->
<!-- begin -->
<servlet>
<servlet-name>IncludingServlet</servlet-name>
<servlet-class>org.it315.ch5.inc.IncludingServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>IncludingServlet</servlet-name>
<url-pattern>/ch5/IncludingServlet</url-pattern>
</servlet-mapping>
<!--end -->
页面通过以下html访问即可。
<a href="IncludingServlet" >including,此时被引入的servlet——IncludedServlet并获得不到参数。</a> <br/>
<a href="IncludingServlet?p1=test测试" >including传参数,此时被引入的servlet类IncludedServlet可以获得到参数</a>
分析:
为什么调用IncludingServlet,并在IncludingServlet中加入
RequestDispatcher rd = getServletContext().getRequestDispatcher(
"/IncludedServlet?p1=" + china);
确在IncludingServlet中确得不到参数呢??(这也命中注定“<jsp:include page="../common/nav.jsp?flag=1" />”这种方式传递参数是不可行的)
这是因为: includingServlet 和IncludingServlet使用的是一个HttpServletRequest对象和一个IncludedServlet对象。上面的方法并没有重新创建一个Request请求,虽然他的外表极为相像。
1.2 forward
mvc控制器所仰仗的就是该方法,学习了forward和过滤器,相信就可以实现自己的mvc了。
forward的使用示例代码如下:
调用者
package org.it315.ch5.forward;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class ForwardingServlet extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
// 禁止浏览器缓存,以免影响实验效果
response.setDateHeader("Expires", 0);
response.setHeader("Cache-Control", "no-cache");
response.setHeader("Pragma", "no-cache");
PrintWriter out = response.getWriter();
// 下面这些输出,将会在调用rd.forward(request, response);方法后被web容器清空
out.println("before forward");// 这些输错
// 用于将缓冲区中的内容强制刷新到客户端,如果调用了rd.forward(request, response)则抛出异常。
// response.flushBuffer();
String china = "中国";
// 不同于rd.include(request, response),该参数值可以成功的传递过去。另外,这里是ch5开头的,是从web应用路径径算起的。
RequestDispatcher rd = getServletContext().getRequestDispatcher(
"/ch5/ForwardedServlet?p1="
+ java.net.URLEncoder.encode(china, "GB2312"));
/**
* 与rd.include(request, response)不同,调用rd.forward(request, response)方法后,
* web容器首先会清空“响应体内容”
*/
rd.forward(request, response);
// 由于之前调用了rd.forward(request, response)方法,下面的输出将会被忽略
out.println("after forwarding");
System.out.println("after forwarding");
}
}
被调用者
package org.it315.ch5.forward;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
public class ForwardedServlet extends HttpServlet {
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
/***
* 与被include不同,被forward时,下面的response.setContentType将会覆盖调用者的response.
* setContentType。
* 不过前提是,在调用setContentType()方法之前没有调用response.getWriter()方法。
*/
response.setContentType("text/html;charset=GB2312");
PrintWriter out = response.getWriter();
/*
* String basePath = request.getScheme() + "://"+
* request.getServerName() + ":" + request.getServerPort() +
* request.getRequestURI(); out.println("<base href=\"" + basePath +
* "\">");
*/
out.println("<a href='ForwardedServlet'>访问自己</a><br>");
out.println("URI:" + request.getRequestURI() + "<br>");
out.println("QueryString:" + request.getQueryString() + "<br>");
out.println("URL:" + request.getRequestURL() + "<br>");
String p1 = request.getParameter("p1");
String chP1 = null;
if (p1 != null) {
chP1 = new String(p1.getBytes("iso8859-1"), "GB2312");
}
out.println("parameter p1:" + chP1 + "<br>");
}
}
对应的web.xml配置如下:
<!--ForwardTest begin -->
<servlet>
<servlet-name>ForwardingServlet</servlet-name>
<servlet-class>org.it315.ch5.forward.ForwardingServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ForwardingServlet</servlet-name>
<url-pattern>/ch5/ForwardingServlet</url-pattern>
</servlet-mapping>
<servlet>
<servlet-name>ForwardedServlet</servlet-name>
<servlet-class>org.it315.ch5.forward.ForwardedServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>ForwardedServlet</servlet-name>
<url-pattern>/ch5/ForwardedServlet</url-pattern>
</servlet-mapping>
<!--ForwardTest end -->
访问链接:http://localhost:8080/Test_servlet/ForwardedServlet
1.3 include和forward的区别
1.3.1 相同点
a.这两个方法都来自RequestDispatcher 类(嘿嘿,被人抽)
b.这两个方法都是在服务端执行,这不同于HttpServletResponse中的sendRedirect(String paramString)方法(sendRedirect方法是通过发送“消息头”,让浏览器去重新指定的)。
c.调用者和被调用者用的都是一组HttpServletResponse和HttpServletRequest对象,并未创建新的对象。
d.访问路径没有变化
e.都只能访问当前web应用中的资源,不同于HttpServletResponse中的sendRedirect(String paramString)。
1.3.2不同点
a.include将是被调用的页面和调用的页面显示在一起;而forward后,只会显示被调用者的页面。
b.include不会传递在 getRequestDispatcher 方法中添加的参数,如下:
RequestDispatcher rd = getServletContext().getRequestDispatcher(
"/*Servlet?p1=" + china);
不过你可以通过在调用者上加入参数以达到目的,前面有讲;而forward可以通过getRequestDispatcher 方法传递参数。
c.include中,被调用的servlet将调用response.setContentType("text/html;charset=GB2312");等方法将不会起作用。forward中,被调用的servlet将调用response.setContentType("text/html;charset=GB2312");将会冲掉调用者servlet的设置(前提是调用者中没有使用response.getWriter();)。
d.实际上,include中不调用PrintWriter out = response.getWriter();是一个很诧异的行为;而在forward中调用PrintWriter out = response.getWriter();确实一个很250的行为,毕竟forward主要用于跳转。
e.访问路径差别,对于代码
RequestDispatcher rd = getServletContext().getRequestDispatcher(
"/ch5/testServlet);
foward访问的是: web应用路径/ch5/testServlet。即:
http://localhost:8080/Test_servlet/ch5/testServlet
而include访问的路径则是:当前路径/ch5/testServlet。例如,如果调用者本身的路径为“http://localhost:8080/Test_servlet/ch5/IncludingServlet”。那么访问的路径将等同为:
http://localhost:8080/Test_servlet/ch5/ch5/testServlet
参考:《深入体验Java_Web开发内幕-核心基础\》
……
分享到:
相关推荐
JavaEE源代码 jstl-1.2JavaEE源代码 jstl-1.2JavaEE源代码 jstl-1.2JavaEE源代码 jstl-1.2JavaEE源代码 jstl-1.2JavaEE源代码 jstl-1.2JavaEE源代码 jstl-1.2JavaEE源代码 jstl-1.2JavaEE源代码 jstl-1.2JavaEE源...
JavaEE源代码 asm-2.2.2JavaEE源代码 asm-2.2.2JavaEE源代码 asm-2.2.2JavaEE源代码 asm-2.2.2JavaEE源代码 asm-2.2.2JavaEE源代码 asm-2.2.2JavaEE源代码 asm-2.2.2JavaEE源代码 asm-2.2.2JavaEE源代码 asm-2.2.2...
JavaEE源代码 xwork-2.0.4JavaEE源代码 xwork-2.0.4JavaEE源代码 xwork-2.0.4JavaEE源代码 xwork-2.0.4JavaEE源代码 xwork-2.0.4JavaEE源代码 xwork-2.0.4JavaEE源代码 xwork-2.0.4JavaEE源代码 xwork-2.0.4JavaEE源...
JavaEE源代码 cglib-2.1.3JavaEE源代码 cglib-2.1.3JavaEE源代码 cglib-2.1.3JavaEE源代码 cglib-2.1.3JavaEE源代码 cglib-2.1.3JavaEE源代码 cglib-2.1.3JavaEE源代码 cglib-2.1.3JavaEE源代码 cglib-2.1.3JavaEE源...
JavaEE源代码 ognl-2.6.11JavaEE源代码 ognl-2.6.11JavaEE源代码 ognl-2.6.11JavaEE源代码 ognl-2.6.11JavaEE源代码 ognl-2.6.11JavaEE源代码 ognl-2.6.11JavaEE源代码 ognl-2.6.11JavaEE源代码 ognl-2.6.11JavaEE源...
JavaEE源代码 oscache-2.1JavaEE源代码 oscache-2.1JavaEE源代码 oscache-2.1JavaEE源代码 oscache-2.1JavaEE源代码 oscache-2.1JavaEE源代码 oscache-2.1JavaEE源代码 oscache-2.1JavaEE源代码 oscache-2.1JavaEE源...
JavaEE源代码 ehcache-1.1JavaEE源代码 ehcache-1.1JavaEE源代码 ehcache-1.1JavaEE源代码 ehcache-1.1JavaEE源代码 ehcache-1.1JavaEE源代码 ehcache-1.1JavaEE源代码 ehcache-1.1JavaEE源代码 ehcache-1.1JavaEE源...
JavaEE源代码 jgroups-2.2.8JavaEE源代码 jgroups-2.2.8JavaEE源代码 jgroups-2.2.8JavaEE源代码 jgroups-2.2.8JavaEE源代码 jgroups-2.2.8JavaEE源代码 jgroups-2.2.8JavaEE源代码 jgroups-2.2.8JavaEE源代码 ...
JavaEE源代码 proxool-0.8.3JavaEE源代码 proxool-0.8.3JavaEE源代码 proxool-0.8.3JavaEE源代码 proxool-0.8.3JavaEE源代码 proxool-0.8.3JavaEE源代码 proxool-0.8.3JavaEE源代码 proxool-0.8.3JavaEE源代码 ...
JavaEE源代码 swarmcache-1.0rc2JavaEE源代码 swarmcache-1.0rc2JavaEE源代码 swarmcache-1.0rc2JavaEE源代码 swarmcache-1.0rc2JavaEE源代码 swarmcache-1.0rc2JavaEE源代码 swarmcache-1.0rc2JavaEE源代码 ...
JavaEE源代码 spring-hibernate3JavaEE源代码 spring-hibernate3JavaEE源代码 spring-hibernate3JavaEE源代码 spring-hibernate3JavaEE源代码 spring-hibernate3JavaEE源代码 spring-hibernate3JavaEE源代码 spring-...
JavaEE源代码 commons-logging-1.0.4JavaEE源代码 commons-logging-1.0.4JavaEE源代码 commons-logging-1.0.4JavaEE源代码 commons-logging-1.0.4JavaEE源代码 commons-logging-1.0.4JavaEE源代码 commons-logging-...
JavaEE源代码 freemarker-2.3.8JavaEE源代码 freemarker-2.3.8JavaEE源代码 freemarker-2.3.8JavaEE源代码 freemarker-2.3.8JavaEE源代码 freemarker-2.3.8JavaEE源代码 freemarker-2.3.8JavaEE源代码 freemarker-...
JavaEE源代码 concurrent-1.3.2JavaEE源代码 concurrent-1.3.2JavaEE源代码 concurrent-1.3.2JavaEE源代码 concurrent-1.3.2JavaEE源代码 concurrent-1.3.2JavaEE源代码 concurrent-1.3.2JavaEE源代码 concurrent-...
JavaEE源代码 jaxen-1.1-beta-7JavaEE源代码 jaxen-1.1-beta-7JavaEE源代码 jaxen-1.1-beta-7JavaEE源代码 jaxen-1.1-beta-7JavaEE源代码 jaxen-1.1-beta-7JavaEE源代码 jaxen-1.1-beta-7JavaEE源代码 jaxen-1.1-...
JavaEE源代码 commons-collections-2.1.1JavaEE源代码 commons-collections-2.1.1JavaEE源代码 commons-collections-2.1.1JavaEE源代码 commons-collections-2.1.1JavaEE源代码 commons-collections-2.1.1JavaEE源...
javaee-api-8.0-javadoc.jar,这是javaee1.8api的jar包,解压后可用javadoc2chm制作成chm帮助文档。
JavaEE源代码 struts2-core-2.0.11JavaEE源代码 struts2-core-2.0.11JavaEE源代码 struts2-core-2.0.11JavaEE源代码 struts2-core-2.0.11JavaEE源代码 struts2-core-2.0.11JavaEE源代码 struts2-core-2.0.11JavaEE源...
JavaEE源代码 jsf-apiJavaEE源代码 jsf-apiJavaEE源代码 jsf-apiJavaEE源代码 jsf-apiJavaEE源代码 jsf-apiJavaEE源代码 jsf-apiJavaEE源代码 jsf-apiJavaEE源代码 jsf-apiJavaEE源代码 jsf-apiJavaEE源代码 jsf-...
JavaEE源代码 struts2-spring-plugin-2.0.11JavaEE源代码 struts2-spring-plugin-2.0.11JavaEE源代码 struts2-spring-plugin-2.0.11JavaEE源代码 struts2-spring-plugin-2.0.11JavaEE源代码 struts2-spring-plugin-...