Servlet介绍(7)-----HttpServletRequest、HttpSession、ServletContext、RequestDispatcher

原创   Servlet介绍(7)-----HttpServletRequest、HttpSession、ServletContext、RequestDispatcher 收藏

<script type="text/javascript"> document.body.oncopy = function() { if (window.clipboardData) { setTimeout(function() { var text = clipboardData.getData("text"); if (text && text.length>300) { text = text + "/r/n/n本文来自CSDN博客,转载请标明出处:" + location.href; clipboardData.setData("text", text); } }, 100); } } </script> <script class="blogstory">function StorePage(){d=document;t=d.selection?(d.selection.type!='None'?d.selection.createRange().text:''):(d.getSelection?d.getSelection():'');void(keyit=window.open('http://www.365key.com/storeit.aspx?t='+escape(d.title)+'&u='+escape(d.location.href)+'&c='+escape(t),'keyit','scrollbars=no,width=475,height=575,left=75,top=20,status=no,resizable=yes'));keyit.focus();}</script>

Servlet 中的几个对象:

HttpServletRequest HttpSession ServletContext ,这三个对象都有

void setAttribute(String name,  Object o) void removeAttribute(String name)

这两个方法,通过这两个方法我们可以很方便的进行参数的传递。

三个对象的作用域的大小分别由小到大。当我们把一个对象通过 void setAttribute(String name,  Object o) 添加到这三个对象中的时候,除非我们显示的调用 void removeAttribute(String name) 或者当这三个对象自己销毁否则不会释放这些对象占用的空间,所以我们在将一个对象通过 setAttribute 添加到这三个对象时,需要注意用完了就 remove ( 当然用完以后这个添加到的对象本身就快销毁时,我们也没必要多此一举 ) 。而且尽量当对象存放在 HttpServletRequest ,然后才是 HttpSession 最后才是 ServletContext 。尽量不要把大对象存放在这些对象中,因为一个进程占用的资源毕竟是有限的。

 

 

Servlet 中路径跳转的问题:

   

让我们先通过一个例子来看一下 HttpServletRequest 的获取路径的一些方法的返回值。

 

ServletPath:

package  squall.servlet.path;

 

import  java.io.IOException;

import  java.io.PrintWriter;

 

import  javax.servlet.ServletException;

import  javax.servlet.http.HttpServlet;

import  javax.servlet.http.HttpServletRequest;

import  javax.servlet.http.HttpServletResponse;

 

 

public   class  ServletPath  extends  HttpServlet

{

 

       
protected   void  doGet(HttpServletRequest req, HttpServletResponse resp)

                     
throws  ServletException, IOException

       
{

              showParam(req,resp);

       }


 

       
protected   void  doPost(HttpServletRequest req, HttpServletResponse resp)

                     
throws  ServletException, IOException

       
{

              showParam(req,resp);

       }


       
private   void  showParam(HttpServletRequest req, HttpServletResponse resp)  throws  IOException

       
{

              resp.setContentType(
" text/html " );

              PrintWriter out 
=  resp.getWriter();

              String docType 
=   " <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> " ;

 

              

              out.println(docType 
+   " <HTML> "   +   " <HEAD><TITLE> pathshow "  

                            
+   " </TITLE></HEAD> "   +   " <BODY BGCOLOR="#FDF5E6"> "

                            
+ " getContextPath():   "   +  req.getContextPath()  +   "    </br> "

                            
+ " getPathInfo():         "   +  req.getPathInfo()  +   "    </br> "

                            
+ " getRequestURI():    "   +  req.getRequestURI() +   "    </br> "

                            
+ " getRequestURL():    "   +  req.getRequestURL() +   "    </br> "

                            
+ " getServletPath():    "   +  req.getServletPath() +   "    </br> "

                            
+ " getQueryString():   "   +  req.getQueryString() +   "    </br> "

                            );

 

          out.println(
" </body></html> " );

       }


       

}


 

将此 Servlet 部署后, mapping <url-pattern>/ServletPath/*</url-pattern>

在浏览器输入 http://127.0.0.1:8080/train/ServletPath/a/b/c?name=1&passord=2

可以看到如下输出:

getContextPath(): /train
     getPathInfo(): /a/b/c
     getRequestURI(): /train/ServletPath/a/b/c
     getRequestURL(): http://127.0.0.1:8080/train/ServletPath/a/b/c
     getServletPath(): /ServletPath
     getQueryString(): name=1&passord=2

 

我们可以很清楚的看到各个方法的返回值的情况。

 

     一个 html,Servlet,jsp 访问另外一个 Servlet 时候可以通过相对路径 ( 相对于当前的路径 ) ,相对于同一 Web 应用下的路径 ( 比如我们的 /train ,通过 request.getContextPath() 获得 ) 和绝对路径 ( 直接 http://...)

 

我们一般在 Servlet 中访问另外一个 Servlet 或者 jsp 可以通过 Servlet 输出中的 HTML 元素 FORM 的属性值 ACTION 来实现。但是我们有时候可以采用一些更加方便的方法。

 

 

 

下面简单的介绍 3 个方法:

RequestDispatcher

     void forward(ServletRequest request, ServletResponse response)

     void include(ServletRequest request, ServletResponse response) 方法。

  HttpResponse void sendRedirect(String location) 方法。

 

  我们先来介绍 HttpResponse void sendRedirect(String location) 方法。

这个方法将请求一个 url location 的页面 , location 可以是一个相对路径、相对于当前 WEB 应用的路径或者直接 Http 开头的路径,下面让我们看一个例子吧。

BeforeSendRedirect

 

package  squall.servlet.path;

 

import  java.io.IOException;

import  java.io.PrintWriter;

 

import  javax.servlet.ServletException;

import  javax.servlet.http.HttpServlet;

import  javax.servlet.http.HttpServletRequest;

import  javax.servlet.http.HttpServletResponse;

 

public   class  BeforeSendRedirect  extends  HttpServlet

{

 

       
protected   void  doGet(HttpServletRequest req, HttpServletResponse resp)

                     
throws  ServletException, IOException

       
{

              resp.setContentType(
" text/html " );

              PrintWriter out 
=  resp.getWriter();

              String docType 
=   " <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> " ;

              req.setAttribute(
" canyousee " " this " );

              

              out.println(docType 
+   " <HTML> "   +   " <HEAD><TITLE> BeforeSendRedirect "  

                            
+   " </TITLE></HEAD> "   +   " <BODY BGCOLOR="#FDF5E6"> "

                            
+ "      <h1>BeforeSendRedirect</h1>    </br> "

                            );

                 out.println(
" </body></html> " ); 

              resp.sendRedirect(
" AfterSendRedirect " );

       

         System.err.println(
" canyousee  "   +  req.getAttribute( " canyousee " +   "  in BeforeSendRedirect " );

         System.err.println(
" end in BeforeSendRedirect " );

       }


 

       
protected   void  doPost(HttpServletRequest req, HttpServletResponse resp)

                     
throws  ServletException, IOException

       
{

              doGet(req,resp);

       }


       

}


 

 

AfterSendRedirect

 

package  squall.servlet.path;

 

import  java.io.IOException;

import  java.io.PrintWriter;

 

import  javax.servlet.ServletException;

import  javax.servlet.http.HttpServlet;

import  javax.servlet.http.HttpServletRequest;

import  javax.servlet.http.HttpServletResponse;

 

public   class  AfterSendRedirect  extends  HttpServlet

{

       
protected   void  doGet(HttpServletRequest req, HttpServletResponse resp)

                     
throws  ServletException, IOException

       
{

              System.err.println(
" begin AfterSendRedirect! " );

              resp.setContentType(
" text/html " );

              PrintWriter out 
=  resp.getWriter();

              String docType 
=   " <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> " ;

              

              out.println(docType 
+   " <HTML> "   +   " <HEAD><TITLE> AfterSendRedirect "

                            
+   " </TITLE></HEAD> "   +   " <BODY BGCOLOR="#FDF5E6"> "

                            
+   "      <h1>AfterSendRedirect</h1>    </br> " );

              out.println(
" </body></html> " );

              System.err.println(
" canyousee  "   +  req.getAttribute( " canyousee " +   "  in AfterSendRedirect " );

       }


 

       
protected   void  doPost(HttpServletRequest req, HttpServletResponse resp)

                     
throws  ServletException, IOException

       
{

              doGet(req, resp);

       }


}


 

 

BeforeSendRedirect mapping <url-pattern>/BeforeSendRedirect</url-pattern>

BeforeSendRedirect mapping <url-pattern>/AfterSendRedirect</url-pattern>

然后我们访问 http://127.0.0.1:8080/train/BeforeSendRedirect ,可以看到页面跳转到 http://127.0.0.1:8080/train/AfterSendRedirect ,并且页面上显示的内容也是

AfterSendRedirect

并且 tomcat 控制台输出为:

canyousee this in BeforeSendRedirect

end in BeforeSendRedirect

begin AfterSendRedirect

canyousee null in AfterSendRedirect

 

可以看出使用 HttpResponse void sendRedirect(String location) 方法

1、             html 页面会显示 location 所输出 的页面

2、            浏览器上的 url 也为 location 的绝对路径

3、            servlet 调用 void sendRedirect(String location) 方法后,剩下的代码也会执行

4、            servlet 和跳转至的 servlet HttpServletRequest 对象不是同一个对象。

 

下面该是

RequestDispatcher

     void forward(ServletRequest request, ServletResponse response)

     void include(ServletRequest request, ServletResponse response) 方法的介绍。

       在这之前,我们先来看下 javax.servlet.RequestDispatcher 对象的获得方法。

获得这个对象的方法,存在于 3 个类或者接口中分别是 ServletContext ServletRequest ServletRequestWrapper 。这里我们只看 ServletContext ServletRequest

ServletContext ServletRequest 中获取 RequestDispatcher 都是通过方法 RequestDispatcher getRequestDispatcher(String path) ,但是需要注意这个方法在用不同的类调用的时候存在一些差异,使用 ServletContext 接口的对象调用时, String path 的参数必须以 ”/” 开头,也就是说从这个 web 项目的根开始。而使用 ServletRequest 接口的对象调用这个方法时, path 可以不以 ”/” 开头,简单的说就是可以使用相对于当前请求的相对路径。

下面我们先来看 RequestDispatcher void forward(ServletRequest request, ServletResponse response) 方法,按照惯例,我们还是用例子来说明问题。

 

BeforeForward

package  squall.servlet.path;

 

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  BeforeForward  extends  HttpServlet

{

       
protected   void  doGet(HttpServletRequest req, HttpServletResponse resp)

                     
throws  ServletException, IOException

       
{

              resp.setContentType(
" text/html " );

              PrintWriter out 
=  resp.getWriter();

              String docType 
=   " <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> " ;

              req.setAttribute(
" canyousee " " this " );

 

              out.println(docType 
+   " <HTML> "   +   " <HEAD><TITLE> BeforeForward "

                            
+   " </TITLE></HEAD> "   +   " <BODY BGCOLOR="#FDF5E6"> "

                            
+   "      <h1>BeforeForward</h1>    </br> " );

              out.println(
" </body></html> " );

              RequestDispatcher rd 
=   this .getServletContext().getRequestDispatcher( " /AfterForward " );

              System.err.println(
" canyousee  "   +  req.getAttribute( " canyousee " )

                            
+   "  in BeforeForward " );

              rd.forward(req, resp);

 

              System.err.println(
" end in BeforeForward " );

       }


 

       
protected   void  doPost(HttpServletRequest req, HttpServletResponse resp)

                     
throws  ServletException, IOException

       
{

              doGet(req, resp);

       }


}


 

 

AfterForward

 

package  squall.servlet.path;

 

import  java.io.IOException;

import  java.io.PrintWriter;

 

import  javax.servlet.ServletException;

import  javax.servlet.http.HttpServlet;

import  javax.servlet.http.HttpServletRequest;

import  javax.servlet.http.HttpServletResponse;

 

public   class  AfterForward  extends  HttpServlet

{

       
protected   void  doGet(HttpServletRequest req, HttpServletResponse resp)

                     
throws  ServletException, IOException

       
{

              System.err.println(
" begin AfterForward! " );

              resp.setContentType(
" text/html " );

              PrintWriter out 
=  resp.getWriter();

              String docType 
=   " <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> " ;

 

              out.println(docType 
+   " <HTML> "   +   " <HEAD><TITLE> AfterForward "

                            
+   " </TITLE></HEAD> "   +   " <BODY BGCOLOR="#FDF5E6"> "

                            
+   "      <h1>AfterForward</h1>    </br> " );

              out.println(
" </body></html> " );

              System.err.println(
" canyousee  "   +  req.getAttribute( " canyousee " )

                            
+   "  in AfterForward " );

       }


 

       
protected   void  doPost(HttpServletRequest req, HttpServletResponse resp)

                     
throws  ServletException, IOException

       
{

              doGet(req, resp);

       }


}


 

BeforeForward AfterForward 分别 mapping <url-pattern>/BeforeForward</url-pattern> <url-pattern>/AfterForward</url-pattern>

 

可以看到控制台输出如下:

canyousee this in BeforeForward

begin AfterForward!

canyousee this in AfterForward

end in BeforeForward

 

浏览器上显示的为:

  AfterForward

浏览器上 url http://127.0.0.1:8080/train/BeforeForward

 

从结果我们可以看到

1、             forward 会显示 forward 后的页面的内容

2、            forward 调用后浏览器的 url 不会变化

3、            forward 后的页面和原页面的 request 为同一对象

 

 

下面是 RequestDispatcher void include(ServletRequest request, ServletResponse response) 例子了,这个例子里,我们使用 request 来获取 RequestDispatcher 对象,所以可以使用相对路径。

BeforeInclude

package  squall.servlet.path;

 

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  BeforeInclude  extends  HttpServlet

{

       
protected   void  doGet(HttpServletRequest req, HttpServletResponse resp)

                     
throws  ServletException, IOException

       
{

              resp.setContentType(
" text/html " );

              PrintWriter out 
=  resp.getWriter();

              String docType 
=   " <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> " ;

              req.setAttribute(
" canyousee " " this " );

 

              out.println(docType 
+   " <HTML> "   +   " <HEAD><TITLE> BeforeInclude "

                            
+   " </TITLE></HEAD> "   +   " <BODY BGCOLOR="#FDF5E6"> "

                            
+   "      <h1>BeforeInclude</h1>    </br> " );

              

              RequestDispatcher rd 
=  req.getRequestDispatcher(

                            
" InInclude " );

              System.err.println(
" canyousee  "   +  req.getAttribute( " canyousee " )

                            
+   "  in BeforeInclude " );

              rd.include(req, resp);

              out.println(
"      <h1>AfterInclude</h1>    </br> " );

              out.println(
" </body></html> " );

              System.err.println(
" end in BeforeInclude " );

       }


 

       
protected   void  doPost(HttpServletRequest req, HttpServletResponse resp)

                     
throws  ServletException, IOException

       
{

              doGet(req, resp);

       }


}


 

InInclude

 

package  squall.servlet.path;

 

import  java.io.IOException;

import  java.io.PrintWriter;

 

import  javax.servlet.ServletException;

import  javax.servlet.http.HttpServlet;

import  javax.servlet.http.HttpServletRequest;

import  javax.servlet.http.HttpServletResponse;

 

public   class  InInclude  extends  HttpServlet

{

       
protected   void  doGet(HttpServletRequest req, HttpServletResponse resp)

                     
throws  ServletException, IOException

       
{

              System.err.println(
" In InInclude! " );

              PrintWriter out 
=  resp.getWriter();

              out.println( 
"      <h1>In InClude</h1>    </br> " );

              System.err.println(
" canyousee  "   +  req.getAttribute( " canyousee " )

                            
+   "  in InInclude " );

       }


 

       
protected   void  doPost(HttpServletRequest req, HttpServletResponse resp)

                     
throws  ServletException, IOException

       
{

              doGet(req, resp);

       }


}


 

 

BeforeInclude InInclude 分别 mapping <url-pattern>/path/BeforeInclude</url-pattern> <url-pattern>/path/InInclude</url-pattern>

 

访问 http://127.0.0.1:8080/train/path/BeforeInclude

可以看到浏览器显示为:

BeforeInclude

 

In InClude

 

AfterInclude

而控制台输出为:

canyousee this in BeforeInclude

In InInclude!

canyousee this in InInclude

end in BeforeInclude

 

需要注意的是上面的例子中的 InInclude 无法输出一个完整的 html 页面。

从结果可以看出:

1、             include 会显示原页面中 include 的地方显示 include Servlet 输出的内容

2、            forward 调用后浏览器的 url 不会变化

3、            forward 后的页面和原页面的 request 为同一对象

 

还是要强调一下 InInclude 无法输出一个完整的 html 页面,它只是输出一部分东西而已。

讲到这里基本上 servlet 中请求的转发和跳转已经讲完了。

 

http://blog.csdn.net/Squall1009/archive/2008/04/14/2290724.aspx

 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值