[原创]
--Email:jiangguilong2000@tom.com --MSN:jiangguilong2000@tom.com --Yahoo ID:allen_jiangguilong --Homepage:liuzi.roboticfan.com --Copyright Allen Jiang --Date:2007-04-18 要讨论Action(extends HttpServlet)与JSP间数据传递问题,首先需准备一下JSP内置对象page, request, session,application的相关知识点,它们的区别何在呢? page:范围最小,只在单个页面中有效; request:范围大一些,可以在指定的页面间传递数据,request和page的生命周期都是短暂的,他们之间的区别就是:一个request可以包含多个page页(include,forward以及filter); session:作用范围是在整个会话,只要浏览器不关,他所衍生出的所有页面都可以共享其中的数据(如果开了两个IE浏览器的话,那就存在两个session); application:范围最大,整个网站都可以看到它的数据(运行在同一tomcat下的Web程序都共享数据)。全局作用范围,整个应用程序共享,就是在部署文件中的同一个webApp共享,生命周期为:应用程序启动到停止(从tomcat启动到停止); 在应用中,应该尽可能缩小共享范围,可以用第一级的就不要用高一级的,这样可以节约资源,提高效率。 ---------- 下面重点来谈谈request与session在数据传递中的区别。 首先大家看web.xml的配置:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN" "http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app> <!--servlet mappings start --> <servlet> <servlet-name>memeber-index</servlet-name> <servlet-class>com.webex.tmis.Action</servlet-class> </servlet> <servlet> <servlet-name>showDetail</servlet-name> <servlet-class>com.webex.tmis.ShowDetailAction</servlet-class> </servlet>
<!--servlet mappings end --> <servlet-mapping> <servlet-name>memeber-index</servlet-name> <url-pattern>/member</url-pattern> </servlet-mapping> <servlet-mapping> <servlet-name>showDetail</servlet-name> <url-pattern>/showDetail</url-pattern> </servlet-mapping>
<!-- The Welcome File List --> <welcome-file-list> <welcome-file>member</welcome-file> </welcome-file-list>
</web-app>
启动tomcat后,当键入http://127.0.0.1:8080/Tmis5.0/,自然,程序会首先触发Action.java,大家请看Action.java的代码:
import java.io.IOException;
import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession;
import org.apache.log4j.Logger; import org.dom4j.Document;
import com.webex.tmis.util.XMLUtil;
public final class Action extends HttpServlet { private Document document = null;
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { document = XMLUtil.convertXMLFile2Document(Constant.INFO_RELATIVEFILEPATH); HttpSession session = req.getSession(); try { session.setAttribute(Constant.EMPLOYEE_LIST_KEY, XMLUtil .getSimpleBeanMapByXML(document, Constant.EMPLOYEE_XPARH)); } catch (Exception e) { System.out.println("error: " + e.getMessage()); }
String target = "/Tmis4.0/index.jsp"; resp.sendRedirect(target); } }
大家看到了,通过Action.java,页面会指向member_index.jsp,值也相应传向该页面,同时由该页面衍生出的所有页面都可以共享该页面取得的数据。在其他页面中如何取值呢?请看members.jsp的部分代码: Map map = (Map) session.getAttribute(Constant.EMPLOYEE_LIST_KEY);这样,就取得了传递过来的值。 现在我们要把JSP内置对象改成request,由于request必须指定页面(可以在action类中指定或者在JSP页面代码中指定),才能使数据进行action与页面传递或者页面与页面间传递。分类讨论: 1.1 action与页面数据传递(1个action对1个页面) Action.java
import java.io.IOException;
import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import com.webex.tmis.util.XMLUtil; public final class Action extends HttpServlet { private Document document = null;
protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { document = XMLUtil.convertXMLFile2Document(Constant.INFO_RELATIVEFILEPATH); try { req.setAttribute(Constant.EMPLOYEE_LIST_KEY, XMLUtil .getSimpleBeanMapByXML(document, Constant.EMPLOYEE_XPARH)); } catch (Exception e) { System.out.println("error: " + e.getMessage()); }
RequestDispatcher requestdispatcher = req.getRequestDispatcher("index.jsp"); requestdispatcher.forward(req, resp); } }
members.jsp中部分代码实现:
Map map = (Map)request.getAttribute(Constant.EMPLOYEE_LIST_KEY);
1.2 action与页面数据传递(1个action对多个页面[一个主页面多个子页面(frame)]) RequestDispatcher对象的include方法,这是一种比较少用的转发请求方式,可以在Servlet中将请求转发给一个页面中包括的所有子页面。给大家举个例子说明一下: 本例子包括三个jsp页面和一个Servlet。 jsp1.jsp: <%@ page contentType="text/html; charset=GBK" %> <html> <body bgcolor="#ffffff"> <h1>JSP1:<%=(String)request.getAttribute("aa")%></h1> </body> </html> -------------------------------- jsp2.jsp: <%@ page contentType="text/html; charset=GBK" %> <html> <body bgcolor="#ffffff"> <h1>JSP2:<%=(String)request.getAttribute("aa")%></h1> </body> </html> -------------------------------- jsp3.jsp:(本页包含以上2个页面,即模版) <%@include file="jsp1.jsp" %> <%@include file="jsp2.jsp" %> -------------------------------- Servlet1.java: public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setAttribute("aa","china");//向request中写个属性 RequestDispatcher rd=request.getRequestDispatcher("jsp1.jsp"); rd.include(request,response);//向jsp1.jsp转发一份request rd=request.getRequestDispatcher("jsp2.jsp"); rd.include(request,response);//向jsp2.jsp转发一份request rd=request.getRequestDispatcher("jsp3.jsp"); rd.forward(request,response);/转发request到jsp3.jsp } 说明:因为jsp3.jsp页面包含了其他两个页面,在Servlet1中将定义请求转发器时包含了另外两个页面。 2.页面与页面数据传递 一个request可以包含多个page页(include,forward以及filter)。举个简单的例子(该例子还讲述了request.getAttribute()与request.getParameter()的区别): HttpServletRequest类既有getAttribute()方法,也由getParameter()方法,这两个方法有以下区别: (1)HttpServletRequest类有setAttribute()方法,而没有setParameter()方法 (2)当两个Web组件之间为链接关系时,被链接的组件通过getParameter()方法来获得请求参数,例如假定welcome.jsp和authenticate.jsp之间为链接关系,welcome.jsp中有以下代码: <a href="/blog/authenticate.jsp?username=weiqin">authenticate.jsp </a> 或者: <form name="form1" method="post" action="authenticate.jsp"> 请输入用户姓名:<input type="text" name="username"> <input type="submit" name="Submit" value="/blog/提交"> </form> 在authenticate.jsp中通过request.getParameter("username")方法来获得请求参数username: <% String username=request.getParameter("username"); %> (3)当两个Web组件之间为转发关系时,转发目标组件通过getAttribute()方法来和转发源组件共享request范围内的数据。假定 authenticate.jsp和hello.jsp之间为转发关系。authenticate.jsp希望向hello.jsp传递当前的用户名字,如何传递这一数据呢?先在authenticate.jsp中调用setAttribute()方法: <% String username=request.getParameter("username"); request.setAttribute("username",username); %> <jsp:forward page="hello.jsp" /> 在hello.jsp中通过getAttribute()方法获得用户名字: <% String username=(String)request.getAttribute("username"); %> Hello: <%=username %> |