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:
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 :
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 :
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 :
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 :
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 :
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 :
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