﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>BlogJava-烦恼岁月-随笔分类-java</title><link>http://www.blogjava.net/hjh/category/27292.html</link><description>付出总是有回报的
take action follow your heart , or follow your head</description><language>zh-cn</language><lastBuildDate>Thu, 22 Nov 2007 17:23:39 GMT</lastBuildDate><pubDate>Thu, 22 Nov 2007 17:23:39 GMT</pubDate><ttl>60</ttl><item><title>servlet/jsp 重定向</title><link>http://www.blogjava.net/hjh/archive/2007/11/16/160937.html</link><dc:creator>不需要解释</dc:creator><author>不需要解释</author><pubDate>Fri, 16 Nov 2007 02:40:00 GMT</pubDate><guid>http://www.blogjava.net/hjh/archive/2007/11/16/160937.html</guid><wfw:comment>http://www.blogjava.net/hjh/comments/160937.html</wfw:comment><comments>http://www.blogjava.net/hjh/archive/2007/11/16/160937.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/hjh/comments/commentRss/160937.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/hjh/services/trackbacks/160937.html</trackback:ping><description><![CDATA[<p>通常，在一个设计良好的Web应用中，都会综合使用Servlet和JSP技术。Servlet控制业务流转，JSP则负责业务处理结果的显示。此时，将大量用到重定向技术。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 重定向技术可以分为两类，一类是客户端重定向，一类是服务器端重定向。客户端重定向可以通过设置特定的HTTP头，或者写JavaScript脚本实现。本文主要探讨服务器端重定向技术的实现。</p>
<p><br />
服务器端的重定向相关类<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 服务器端的重定向技术涉及到javax.servlet.ServletContext、javax.servlet.RequestDispatcher、javax.servlet.http.ServletRequest、javax.servlet.http.ServletResponse等几个接口。<br />
服务器端的重定向方式<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 服务器端的重定向可以有两种方式，一是使用HttpServletResponse的sendRedirect()方法，一是使用RequestDispatcher的forward()方法。下面对这两种方式进行介绍。</p>
<p>HttpServletResponse.sendRedirect()方法</p>
<p>HttpServletResponse接口定义了可用于转向的sendRedirect()方法。代码如下：</p>
<p>public void sendRedirect(java.lang.String location)throws java.io.IOException</p>
<p><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 这个方法将响应定向到参数location指定的、新的URL。location可以是一个绝对的URL，如response.sendRedirect("http://java.sun.com")也可以使用相对的URL。如果location以&#8220;/&#8221;开头，则容器认为相对于当前Web应用的根，否则，容器将解析为相对于当前请求的URL。这种重定向的方法，将导致客户端浏览器的请求URL跳转。从浏览器中的地址栏中可以看到新的URL地址，作用类似于上面设置HTTP响应头信息的实现。</p>
<p>RequestDispatcher.forward()方法</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RequestDispatcher是一个Web资源的包装器，可以用来把当前request传递到该资源，或者把新的资源包括到当前响应中。RequestDispatcher接口中定义了两个方法，参见如下代码：</p>
<p>public interface RequestDispatcher {<br />
void forward(ServletRequest request, ServletResponse response);<br />
void include(ServletRequest request, ServletResponse response);<br />
}</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; forward()方法将当前的request和response重定向到该RequestDispacher指定的资源。这在实际项目中大量使用，因为完成一个业务操作往往需要跨越多个步骤，每一步骤完成相应的处理后，转向到下一个步骤。比如，通常业务处理在Servlet中处理，处理的结果转向到一个JSP页面进行显示。这样看起来类似于Servlet链的功能，但是还有一些区别。一个RequestDispatcher对象可以把请求发送到任意一个服务器资源，而不仅仅是另外一个Servlet。 include()方法将把Request Dispatcher资源的输出包含到当前输出中。</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 注意，只有在尚未向客户端输出响应时才可以调用forward()方法，如果页面缓存不为空，在重定向前将自动清除缓存。否则将抛出一个IllegalStateException异常。</p>
<p><br />
如何得到RequestDispatcher</p>
<p><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 有三种方法可以得到Request Dispatcher对象。</p>
<p>1.javax.servlet. ServletRequest的getRequestDispatcher(String path)方法，其中path可以是相对路径，但不能越出当前Servlet上下文。如果path以&#8220;/&#8221;开头，则解析为相对于当前上下文的根。</p>
<p>2.javax.servlet. ServletContext的getRequestDispatcher(String path)方法，其中path必须以&#8220;/&#8221;开头，路径相对于当前的Servlet上下文。可以调用ServletContext的getContext(String uripath)得到另一个Servlet上下文，并可以转向到外部上下文的一个服务器资源链接。</p>
<p>3.使用javax.servlet. ServletContext的getNamedDispatcher(String name)得到名为name的一个Web资源，包括Servlet和JSP页面。这个资源的名字在Web应用部署描述文件web.xml中指定。<br />
<br />
</p>
<p>这三种方法的使用有细微的差别。比如，下面是一个应用的配置文件web.xml：</p>
<p>&lt;?xml version="1.0" ?&gt;<br />
&lt;!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.2//EN"<br />
"http://java.sun.com/j2ee/dtds/web-app_2_2.dtd"&gt;<br />
&lt;web-app&gt;<br />
&lt;servlet&gt;<br />
&lt;servlet-name&gt;FirstServlet&lt;/servlet-name&gt;<br />
&lt;servlet-class&gt;org. javaresearch.redirecttest.ServletOne&lt;/servlet-class&gt;<br />
&lt;/servlet&gt;<br />
&lt;servlet&gt;<br />
&lt;servlet-name&gt;SecondServlet&lt;/servlet-name&gt;<br />
&lt;servlet-class&gt;org.javaresearch. redirecttest.ServletTwo&lt;/servlet-class&gt;<br />
&lt;/servlet&gt;<br />
&lt;servlet-mapping&gt;<br />
&lt;servlet-name&gt;FirstServlet&lt;/servlet-name&gt;<br />
&lt;url-pattern&gt;/servlet/firstservlet/&lt;/url-pattern&gt;<br />
&lt;/servlet-mapping&gt;<br />
&lt;servlet-mapping&gt;<br />
&lt;servlet-name&gt;SecondServlet&lt;/servlet-name&gt;<br />
&lt;url-pattern&gt;/servlet/secondservlet/&lt;/url-pattern&gt;<br />
&lt;/servlet-mapping&gt;<br />
&lt;/web-app&gt;</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 其中定义了两个Servlet，名字分别为FirstServlet和SecondServlet，对应的类分别为org.javaresearch. redirecttest.ServletOne和org. javaresearch.redirecttest.ServletTwo。可以在浏览器中通过类似于下面的链接访问：</p>
<p>http://localhost:8080/servlet/firstservlet/</p>
<p>使用1中方法，例如在firstservlet可以写入下面的代码：</p>
<p>RequestDispatcher rd = request.getRequestDispatcher("secondservlet");<br />
rd.forward(request, response);</p>
<p>&nbsp;</p>
<p>此时控制权将转向到第二个Servlet了。</p>
<p>使用2中的方法，可以从Servlet Context中得到RequestDispatcher代码如下：</p>
<p>RequestDispatcher rd = getServletContext().getRequest<br />
Dispatcher("/servlet/secondservlet");<br />
rd.forward(request, response);</p>
<p>&nbsp;</p>
<p>使用3中的方法，从上面的web. xml配置文件可以看到定义了两个Servlet，名字分别为FirstServlet和SecondServlet，所以可以得到命名的Dispatcher：</p>
<p>RequestDispatcher rd = getServletContext().getNamedDispatcher("SecondServlet");<br />
rd.forward(request, response);</p>
<p>&nbsp;</p>
<p>这样也可以重定向到SecondServlet了。</p>
<p><br />
JSP页面中的重定向</p>
<p><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JSP在解析后编译为一个Servlet运行，所以在JSP中也可以使用上面的重定向代码，并且，JSP还提供了更便利的操作，如下：</p>
<p>&lt;jsp:forward page= "nextpage.jsp"/&gt;</p>
<p>&nbsp;</p>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JSP页面执行到这儿，将终止当前的处理，将控制权交由nextpage.jsp。</p>
<p><br />
如何选择</p>
<p><br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; RequestDispatcher.forward()方法和HttpServletResponse.sendRedirect()方法的区别是：前者仅是容器中控制权的转向，在客户端浏览器地址栏中不会显示出转向后的地址；后者则是完全的跳转，浏览器将会得到跳转的地址，并重新发送请求链接。这样，从浏览器的地址栏中可以看到跳转后的链接地址。所以，前者更加高效，在前者可以满足需要时，尽量使用Request Dispatcher.forward()方法，并且，这样也有助于隐藏实际的链接。在有些情况下，比如，需要跳转到一个其它服务器上的资源，则必须使用HttpServletResponse.sendRequest()方法<br />
</p>
<p><br />
</p>
 <img src ="http://www.blogjava.net/hjh/aggbug/160937.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/hjh/" target="_blank">不需要解释</a> 2007-11-16 10:40 <a href="http://www.blogjava.net/hjh/archive/2007/11/16/160937.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>