JSP学习 —— 开篇:JSP,servlet容器,Tomcat,servlet容器之间的关系

来源:互联网 发布:js导入导出excel数据 编辑:程序博客网 时间:2024/04/26 22:19
JSP(JAVA SERVER PAGE)的缩写,其本身就是servlet的简化,是一种动态网页标准,其特点是在HTML代码中嵌入JAVA代码,JSP标签或用户标签来生成网页。至于它为什么会出现,主要原因在于早期的servlet技术在编写代码时经常通篇性的写一大堆HTML标签,静态文本及文本格式等表现逻辑,其开发效率非常之低下;为了解决这种情况,便随之出现了JSP,其静态部分(包括表现逻辑,如图片,文字等等)全用HTML语言来编写,只有需要动态生成的逻辑才由嵌入的JAVA代码来实现。

    说到最后,JSP其实还是一种对servlet的简化语言,所有的JSP页面最终都会被servlet容器编译成servlet类(其实就是java类),而至于什么是servlet容器,在此简单说下,仅从字面意思上看,它就是一种存放东西的容器,存放什么东西呢?存放维护和创建servlet相关的逻辑(懂C++的JSP新手注意:千万不要将这里的容器和C++中的VECTOR容器相混淆,这里的容器就是一个简单的存东西的容器)。而servlet的实现逻辑大体如下(5个方法):

[java] view plaincopyprint?
  1. public void init(ServletConfig config)throws ServletException 
  2. public void service(ServletRequest request, ServletResponse response)  
  3. throws ServletException, java.io.IOException 
  4. public void destroy() 
  5. ServletConfig getServletConfig() 
  6. public java.lang.String getServletInfo()   


    最主要的方法就是init,service和destroy,它们是servlet对象的生存周期,当一个页面被编译成servlet类,再进行实例化后,这个页面就开始了真正的生命周期,servlet容器会先加载init方法进行初始化,初始化后才可进行接收和相应客户端的消息,之后容器会再加载service,这部分就是真正相应客户端请求的实现逻辑,它实现客户端的请求响应,然后动态生成HTML页面显示到客户端;而destory方法则是在servlet生命周期即将结束时进行的清理工作。

   而事实上,Tomcat在大多数情况下充当servlet的容器,也就是说:在写完JSP代码后进行第一次执行时,tomcat(servlet容器)先将JSP代码翻译成servlet类(java代码),然后实例化该类,再调用该类的init,service,destory等进行生命周期服务。当客户端再进行第二次访问请求时,此时就没有servlet容器的翻译这一步了,因为之前翻译的java代码会一直保存,以便于后面的访问不再进行翻译,可大大提高访问效率。所以,JSP页面在第一次被访问时,其所花费的时间是最长的。

 

 

1.JSP语句的生明
 
JSP的声明语句格式<%!  %>,,要注意,凡是用JSP声明的变量或函数,在servlet容器翻译成servlet类时,都将其翻译为servlet类的成员变量或函数;当JSP文件被翻译成servlet类后进行实例化时,所有的客户端访问的实例化servlet对象都是同一个对象,这意味着,如果试图对成员变量进行操作,那么其影响可谓是全局性的。来看下下面实例:
 

 

01.<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%> 
02.<% 
03.String path = request.getContextPath(); 
04.String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+path+"/"; 
05.%> 
06. 
07.<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
08.<html> 
09.  <head> 
10.    <base href="<%=basePath%>"> 
11.     
12.    <title>My JSP 'index.jsp' starting page</title> 
13.    <meta http-equiv="pragma" content="no-cache"> 
14.    <meta http-equiv="cache-control" content="no-cache"> 
15.    <meta http-equiv="expires" content="0">     
16.    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> 
17.    <meta http-equiv="description" content="This is my page"> 
18.    <!--
19.    <link rel="stylesheet" type="text/css" href="styles.css">
20.    --> 
21.  </head> 
22.  <%! 
23.    private int count = 0; 
24.    public int getCount() 
25.    { 
26.        count ++ ; 
27.        return count; 
28.    } 
29.  %> 
30.  <body> 
31.    <% 
32.        out.println("the value of count is: " + getCount()); 
33.     %> 
34.  
35.   </body> 
36.</html> 
 
这是一个简单的JSP程序,在第一次运行后,页面结果显示为:the value of count is: 1
 
而进行刷新页面时,每刷新一次,其count值都加1,显示结果也会改变:the value of count is: 2等等。
 
再从浏览器中看下HTLM源代码:
 

 

01.<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"> 
02.<html> 
03.  <head> 
04.    <base href="http://jxpc-001:8080/MyTest/"> 
05.     
06.    <title>My JSP 'index.jsp' starting page</title> 
07.    <meta http-equiv="pragma" content="no-cache"> 
08.    <meta http-equiv="cache-control" content="no-cache"> 
09.    <meta http-equiv="expires" content="0">     
10.    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3"> 
11.    <meta http-equiv="description" content="This is my page"> 
12.    <!--
13.    <link rel="stylesheet" type="text/css" href="styles.css">
14.    --> 
15.  </head> 
16.   
17.  <body> 
18.    the value of count is: 1 
19.  
20.   </body> 
21.</html> 
 
      可以看到,凡是有关jsp声明相关的部分全部没有了,只剩下纯HTML代码。正好印证了前面一篇文章中所说过的话:
 
“容器会再加载service,这部分就是真正相应客户端请求的实现逻辑,它实现客户端的请求响应,然后动态生成HTML页面显示到客户端”
 
 
 
2.JSP的编译指令:include 和 page 
 
   至于上面的JSP文章中开头部分还有一行代码:
 

 

01.<%@ page language="java" import="java.util.*" pageEncoding="ISO-8859-1"%>  
 
  这是一条编译指令,在JSP翻译成servlet类时,用来通知servlet容器的消息,以让其在翻译成servlet类时按照指定的额外要求进行翻译。
 
     说到这,再来探讨下编译指令。常见的编译指令有3条:page(对当前页面的编译要求),include(包含其它页面),和tablib(自定义和访问),其声明方式为<%@  (指令)  [属性 ="..." ] %>, 对于page指令,通常放在JSP文件开头处,一个JSP页面可出现多个page指令,如可将上面的page指令改为:
 

 

01.<%@ page language="java" import="java.util.*"% > 
02. 
03.<%@ page pageEncoding="ISO-8859-1"%>  
 
两行语句来代替,其效果相同。
 
    而对于include指令,<%@ include %>,这是个静态包含语句,servlet容器在包含时对其内容不进行任何检测就将其包含,若其文件内容有误,也在包含进来后进行翻译的时候才检测其内容的正误,这一点与C++中的预编译指令#define有些像,#define只是进行简单的替换,至于其正误,在代码编译时才能检测出来,而在这里<% @ include %>也只是先进行简单的包含,对于其内容要一直等到编译为servlet类时进行检测。
 
   另外编写一个JSP文件,其内容如下:
 

 

01.<%@page import = "java.util.*" %> 
02.<%=new Date() %> 
 

   在之前代码的<body>部分再加一行代码:
 

 

01.<%@include file="includeByIndex.jsp" %> 
 
  执行程序后,结果如下:
 
this is a new JSP page
Tue Aug 09 09:56:23 CST 2011

 
 
3.JSP的几种动作指令
 
  在这里,我们再把之前的include语句替换成如下语句:
 

 

01.<jsp:forward page="includeByIndex.jsp"></jsp:forward> 
 
  includeByIndex.jsp的内容不变,则显示结果又如下:
 
Tue Aug 09 10:11:30 CST 2011

   没有了之前的“this is a new JSP page”,这是因为这里的jsp:forword是个跳转语句,其可跳转到指定的静态或动态页面,或跳转到容器中的servlet。
 
在进行跳转时,还可以进行参数传递,如下:
 

 

01.<jsp:forward page="includeByIndex.jsp"> 
02.    <jsp:param value="James" name="username"/> 
03.</jsp:forward> 
 

将includeByIndex.jsp的内容再改写如下:
 

 

01.<%@ page import="java.util.*"%> 
02.<body> 
03.<%out.println("the param of username is : "); %> 
04.<%=request.getParameter("username") %> 
05.<%out.println("now the time is: "); %> 
06.<%=new Date() %> 
07.</body> 
 

最终页面上的结果为:
 
the param of username is : James now the time is: Tue Aug 09 10:19:40 CST 2011
 
至于接收参数的对象request,再这里先不介绍,以后再进行详细阐述。
 
   我们继续将之前的讲解include源代码基础上再将include语句替换成如下语句:
 

 

01.<jsp:include page="includeByIndex.jsp"></jsp:include> 
 
   其页面显示结果为:
 
this is a new JSP page
Tue Aug 09 10:29:14 CST 2011

  可以看到与没替换之前编译指令include执行效果差不多,那么它们的区别到底在哪呢?区别就在于:编译指令<%@include>只是简单的将源文件包含进来,然后进行执行,而<jsp:include>是个动作指令,它是在将源文件代码进行执行后,再将其结果包含进来进行显示(如果要包含的文件为静态文件,则直接进行显示),简单的说:<%@include>指令先包含,再执行,而<jsp:include>指令先执行,再包含。从servlet容器层面上来看,动态导入时,servlet类中会将<jsp:include>翻译为一条简单的包含语句:
 

 

01.org.apache.jasper.runtime.JspRuntimeLibrary.include(request , response ,"includeByIndex.jsp" , out); 
 
而<%@include>会被容器翻译为JAVA源代码,然后与servlet类一起构成整个文件。   
 
 
 
 
  到这里,JSP单文件处理内容已经差不多了,接下来就是JSP与JAVA类的混合编码,开始步入将业务逻辑与页面实现分离的阶段。
 
  首先来看下3种动作指令:useBean,setProperty,getProperty,其中useBean是进行类的对象的声明语句,setProperty和getProperty是对页类的属性进行操作的语句。
 
   我们先来声明一个自己的JAVA类,代码如下所示:
 

 

01.package com.user; 
02. 
03.public class userInformation { 
04.    private String userName; 
05.    private String userPassword; 
06.     
07.    public String getUserName() { 
08.        return userName; 
09.    } 
10.    public void setUserName(String userName) { 
11.        this.userName = userName; 
12.    } 
13.    public String getUserPassword() { 
14.        return userPassword; 
15.    } 
16.    public void setUserPassword(String userPassword) { 
17.        this.userPassword = userPassword; 
18.    } 
19.} 
 
  在页面中的<body>部分代码如下:
 

 

01.<body> 
02.    <jsp:useBean id="user" class="com.user.userInformation" scope="page"></jsp:useBean> 
03.    <jsp:setProperty property="userName" name="user" value="James"/> 
04.    <jsp:setProperty property="userPassword" name="user" value="123456"/> 
05.    <jsp:getProperty property="userName" name="user"/> 
06.    <jsp:getProperty property="userPassword" name="user"/> 
07.  </body> 
 
  该JSP文件的执行结果为:
 
James 123456

其中<jsp:useBean>的属性id为对象名,class为类名,scope为对象的生存周期,有如下四个可选项:
 page:仅在当前页面有效;
 
request::在一次请求范围内有效,即:如果页面从一个页面转到另一个页面,那么当前对象失效;
 
session:在一次连接范围内有效,如果和服务器断开连接,则当前对象失效;
 
application:从服务器启动到结束一直有效。
 
(至于这几个声明周期,其具体内容较多,在此先不进行详细阐述,会在下一篇文章中介绍。)
 
<jsp:setProperty>属性property为类的属性名,name为对象名,value为值。

 

 

本篇依然为基础篇,主要讲解Jsp的9个内置对象。Jsp的内置对象为Servlet API的类或接口的实例化,它们的实例化过程由Jsp标准自动进行,意即:我们可以直接使用这些对象,而不需要声明它,这些内置对象分别为:application, config,response,request,exception,out,page,pagecontext,session;接下来,我就分别对几个主要对象的特性进行详细阐述:

1.application对象

它是javax.servlet.ServletContext类的对象,一般来说,它就代表整个WEB应用,对于它的属性值,在整个WEB应用(JSP或Servlet类)中都是公用的,最常用的方法是:setAttribute(name,value)和getAttribute(name);为此来做个测试:在同一个WEB工程中编写两个JSP文件,index.jsp如下:

[html] view plaincopyprint?
  1. <%@ page language="java"import="java.util.*" %> 
  2. <%@ page pageEncoding="ISO-8859-1"%> 
  3. <html> 
  4.   <%! 
  5.     private int count =0
  6.     public Integer getCount() 
  7.     { 
  8.         count ++ ; 
  9.         return count; 
  10.     } 
  11.   %> 
  12.   <body> 
  13.     <
  14.         application.setAttribute("count",getCount().toString()); 
  15.         out.println("the value of count is :"+count);     %> 
  16.    </body> 
  17. </html> 

test_application.jsp内容如下:

[html] view plaincopyprint?
  1. <%@page language="java"contentType="text/html; charset=ISO-8859-1"  %> 
  2. <html> 
  3.     <head> 
  4.         <title>测试application</title> 
  5.     </head> 
  6.     <body> 
  7.         <%out.println("get the value of count,the count is a field of application,value: "); %> 
  8.         <%=application.getAttribute("count")%> 
  9.     </body> 
  10. </html> 


我们先启动服务器,访问http://localhost:8080/index.jsp,其结果如下:

the value of count is :2,

每刷新一次页面,count的值就增1,此时我们再访问http://localhost:8080/test_application.jsp,其结果显示如下:

get the value of count,the count is a field of application,value: 2

没有进行任何参数传递,也没有直接获取javabean的属性,而是通过application对象,先设置属性(application.setAttribute("count",getCount().toString());),再从另一个页面中获得属性(application.getAttribute("count"))就能做到属性的全局共享,这便是使用application对象的作用。

application对象的另外一个强大作用就是能用来解析WEB.XML的配置信息,以下就是一个完整的连接和查询mysql数据库的例子,而访问数据库的url,密码,用户名等信息,均存储在web.xml中,在JSP文件中用application对象读取参数属性。

[html] view plaincopyprint?
  1. <%@ page language="java"import="java.util.*" %> 
  2. <%@ page pageEncoding="ISO-8859-1"%> 
  3. <%@page import="java.sql.SQLException"%> 
  4. <%@page import="java.net.ConnectException"%> 
  5. <%@page import="java.sql.DriverManager"%> 
  6. <%@page import="java.sql.*" %> 
  7. <html> 
  8.   <body> 
  9.     <%  
  10.         Connection conn=null
  11.         Statement state=null
  12.         ResultSet rs=null
  13.         String driver=application.getInitParameter("driver"); 
  14.         String url=application.getInitParameter("url"); 
  15.         String user=application.getInitParameter("user"); 
  16.         String password=application.getInitParameter("password"); 
  17.         try{  
  18.              Class.forName(driver); 
  19.              conn=DriverManager.getConnection(url,user,password); 
  20.         }catch(SQLException e) {  
  21.             out.println("failed to connect the db"); 
  22.         } catch(ClassNotFoundException e){ 
  23.             out.println("can't find the driver class"); 
  24.         } 
  25.         try{ 
  26.             state=conn.createStatement(); 
  27.             String queryAll="select*from user_information"
  28.             rs=state.executeQuery(queryAll); 
  29.             while(rs.next()) 
  30.             { 
  31.              int userid=rs.getInt(1); 
  32.              String username=rs.getString(2); 
  33.              String userpassword=rs.getString(3); 
  34.               
  35.              out.println("user id is: "+userid); 
  36.              out.println("user name is: "+username); 
  37.              out.println("user password is: "+userpassword); 
  38.             }  
  39.         }catch(SQLException e){ 
  40.             out.println("research fialed!"); 
  41.         } 
  42.         try{ 
  43.             if(rs != null){ 
  44.                 rs.close(); 
  45.             } 
  46.             if(state != null){ 
  47.                 state.close();           
  48.             } 
  49.             if(conn != null){ 
  50.                 conn.close(); 
  51.             } 
  52.         }catch(Exception e){ 
  53.             out.println("error when close db"); 
  54.         } 
  55.      %> 
  56.    </body> 
  57. </html> 


web.xml的完整信息如下:

[html] view plaincopyprint?
  1. <?xmlversion="1.0"encoding="UTF-8"?> 
  2. <web-app version="2.5"  
  3.     xmlns="http://java.sun.com/xml/ns/javaee"  
  4.     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
  5.     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee  
  6.     http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"> 
  7.   <welcome-file-list> 
  8.     <welcome-file>index.jsp</welcome-file> 
  9.   </welcome-file-list> 
  10.   <context-param> 
  11.         <param-name>driver</param-name> 
  12.         <param-value>com.mysql.jdbc.Driver</param-value> 
  13.   </context-param> 
  14.   <context-param> 
  15.         <param-name>user</param-name> 
  16.         <param-value>root</param-value> 
  17.   </context-param> 
  18.   <context-param> 
  19.         <param-name>password</param-name> 
  20.         <param-value>900622</param-value> 
  21.   </context-param> 
  22.   <context-param> 
  23.         <param-name>url</param-name> 
  24.         <param-value>jdbc:mysql://localhost:3306/test_db</param-value> 
  25.   </context-param> 
  26. </web-app> 


页面执行结果为:

user id is: 1 user name is: James user password is: 123456

2. pageContext对象


pageContext对象可以用来访问和设置各种范围的属性(包括page,request,session和application),事实上,如果给各种范围的属性设置成相同的属性名,那么各属性是互不影响的,这就相当于C++中同名变量在不同的生存范围内互不影响(如同名的全局变量和局部变量),而pageContext通常用来获得和设置各种范围的属性值,看下面实例:

[html] view plaincopyprint?
  1. <body> 
  2.     <
  3.               //使用不同内置对象设置不同范围属性 
  4.               pageContext.setAttribute("name","page_James");  //设置page范围属性 
  5.               request.setAttribute("name","request_James"); //设置request范围属性 
  6.               session.setAttribute("name","session_James"); //设置session范围属性 
  7.               application.setAttribute("name","application_James"); //设置application范围属性 
  8.               //使用pageContext设置不同范围属性 
  9.               pageContext.setAttribute("age","30");  //不指定属性的范围时默认为page范围 
  10.               pageContext.setAttribute("age","40",pageContext.REQUEST_SCOPE); 
  11.               pageContext.setAttribute("age","50",pageContext.SESSION_SCOPE); 
  12.               pageContext.setAttribute("age","60",pageContext.APPLICATION_SCOPE); 
  13.            %> 
  14.            <%="page范围的name值:"+(String)pageContext.getAttribute("name",pageContext.PAGE_SCOPE)%><br/> 
  15.            <%="page范围的age值: "+(String)pageContext.getAttribute("age",pageContext.PAGE_SCOPE) %><br/> 
  16.            <%="request范围name值: "+(String)pageContext.getAttribute("name",pageContext.REQUEST_SCOPE)%><br/> 
  17.            <%="request范围age值:"+(String)pageContext.getAttribute("age",pageContext.REQUEST_SCOPE) %><br/> 
  18.            <%="session范围name值: "+(String)pageContext.getAttribute("name",pageContext.SESSION_SCOPE) %><br/> 
  19.            <%="session范围age值:"+(String)pageContext.getAttribute("age",pageContext.SESSION_SCOPE) %><br/> 
  20.            <%="application范围name值:"+(String)pageContext.getAttribute("name",pageContext.APPLICATION_SCOPE) %><br/> 
  21.            <%="application范围name值:"+(String)pageContext.getAttribute("age",pageContext.APPLICATION_SCOPE) %> 
  22.   </body> 


其页面执行结果如下:

page范围的name值:page_James
page范围的age值: 30
request范围name值: request_James
request范围age值:40
session范围name值: session_James
session范围age值:50
application范围name值:application_James
application范围name值:60


3. request对象

request对象是个很重要的对象,它被用于封装一次的用户请求参数,请求参数可以是表单值,可以是以request对象设置的属性值,也可以是url地址中所附带的少量字符串参数。  我们来看下面实例:

index.jsp的body部分

[html] view plaincopyprint?
  1. <body> 
  2.         <
  3.     ArrayList<String>list = new ArrayList<String>() ; 
  4.     list.add("this"); 
  5.     list.add(" is"); 
  6.     list.add(" the"); 
  7.     list.add(" list"); 
  8.     for(int i = 0 ;i<list.size();i++) 
  9.     { 
  10.         out.println(list.get(i)); 
  11.     } 
  12.     request.setAttribute("list",list); 
  13. %> 
  14.  
  15.         <formaction="request.jsp"id="form"method="post"> 
  16.             用户名:<inputtype="text"name="username"><hr/> 
  17.             密    码:<inputtype="text"name="userpwd"><hr/> 
  18.             <inputtype="submit"value="提   交"> 
  19.         </form> 
  20. </body> 

request.jsp的body部分:

[html] view plaincopyprint?
  1. <body> 
  2.         <%="user name is: "+request.getParameter("username")  %><br/> 
  3.         <%="user password is: "+request.getParameter("userpwd") %><br/> 
  4.         <
  5.             ArrayList<String>list = (ArrayList<String>)request.getAttribute("list"); 
  6.             for(int i = 0 ;i<list.size() ; i++) 
  7.             { 
  8.                 out.println(list.get(i)); 
  9.             } 
  10.          %> 
  11.     </body> 


大概看来,这段代码应该没错,如果我们在“用户名”中输入:james,在“密码”中输入:admin,那么,我们预料的显示结果应该是

user name is :james

user password is: admin

this is the list

而事实上,请求提交后,页面出错,显示一堆错误信息。

在这里要注意,提交请求和页面跳转是两个不同的概念,范围属性和请求参数也是两个不同的概念,提交请求后,请求参数会被servlet封装到request对象中,这一点毋庸置疑,但不会将属性也封装到servlet中,只有当发生< jsp:forward>跳转时,才会将属性提交到要转发的页面,如果我们将index.jsp改为如下:

[html] view plaincopyprint?
  1. <body> 
  2.         <
  3.     ArrayList<String>list = new ArrayList<String>() ; 
  4.     list.add("this"); 
  5.     list.add(" is"); 
  6.     list.add(" the"); 
  7.     list.add(" list"); 
  8.     for(int i = 0 ;i<list.size();i++) 
  9.     { 
  10.         out.println(list.get(i)); 
  11.     } 
  12.     request.setAttribute("list",list); 
  13. %> 
  14. <
  15.     ArrayList<String>list2 = new ArrayList<String>(); 
  16.     list2 = (ArrayList<String>)pageContext.getAttribute("list",pageContext.REQUEST_SCOPE); 
  17.     for(int i = 0 ;i<list2.size() ; i++) 
  18.     { 
  19.         out.println(list.get(i)); 
  20.     } 
  21. %> 
  22. <jsp:forwardpage="request.jsp"></jsp:forward> // !!!!!注意多加了这一句!!! 
  23.         <formaction="request.jsp"id="form"method="post"> 
  24.             用户名:<inputtype="text"name="username"><hr/> 
  25.             密    码:<inputtype="text"name="userpwd"><hr/> 
  26.             <inputtype="submit"value="提   交"> 
  27.         </form> 
  28. </body> 

那么request.jsp的显示内容将又会为:

user name is:null

user password is:null

this is the list

index.jsp中未提交请求前就发生跳转,所以name和password值没有设置,而forward跳转会传递属性,所以会在跳转页面request.jsp中正常接收。


4. response和out对象


response对象和out对象都是用来向页面输出信息的流对象,其不同之处在于:out对象只能输出字符流(只能输出文字),却不能输出字节流(如位图),而response对象却可以做到这一点;在大多数情况下,out完全可以替代response的作用,而有时候response的功能却不容忽视,甚至起关键作用:如可以创建cookie,可以设置定时刷新的页面,可以不使用forward跳转来实现不带属性的跳转。 以下来看一下response创建cookie的示例:

在index.jsp中代码如下:

[html] view plaincopyprint?
  1. <body> 
  2.         <formaction="request.jsp"id="form"method="post"> 
  3.             用户名:<inputtype="text"name="username"><hr/> 
  4.             密    码:<inputtype="text"name="userpwd"><hr/> 
  5.             <inputtype="submit"value="提   交"> 
  6.         </form> 
  7. </body> 


在request.jsp中代码如下:

[html] view plaincopyprint?
  1. <body> 
  2.         <
  3.             String userName =request.getParameter("username");  
  4.             String userPassword = request.getParameter("userpwd"); 
  5.             Cookie nameCookie =new Cookie("username",userName); //创建cookie 
  6.             nameCookie.setMaxAge(24*3600);//设置生存时间为24小时 
  7.             Cookie pwdCookie =new Cookie("userpwd",userPassword); 
  8.             pwdCookie.setMaxAge(24*3600); 
  9.             response.addCookie(nameCookie); //添加cookie 
  10.             response.addCookie(pwdCookie); 
  11.          %> 
  12.                  <jsp:forwardpage="prove.jsp"></jsp:forward>  
  13. </body> 

这样,凡是客户端输出用户名和密码的话,其便会存储在客户端的硬盘中,24小时后就自动清除,如此可以提供更友好的服务。


我们继续创建一个验证页: prove.jsp,其代码如下:

[html] view plaincopyprint?
  1. <body> 
  2.         <
  3.             Cookie cookies[] = request.getCookies(); 
  4.             for(Cookie c:cookies) 
  5.             { 
  6.                 if(c.getName().equals("username") || c.getName().equals("userpwd")) 
  7.                 { 
  8.                     out.println(c.getName()+":"+c.getValue()); 
  9.                 } 
  10.             } 
  11.          %> 
  12.   </body> 


在index.jsp页面中的用户名中填入:James,在密码中输入:admin,

此时页面显示结果为:

username:James    userpwd:admin

事实上,在24小时内任意时间段输入http://jxpc-001:8080/ExtJs/request.jsp,那么网页最终都会显示为这样的结果。

5. session对象

对于session对象,我不打算多述,因为其作用基本与request相同,只是生命周期比request要长,从浏览器打开到关闭浏览器,如同一个单网页下设置了一个session范围属性和request范围属性,当页面关闭时,session范围属性我们可以不用forward跳转而在任何地方获得,其都不会丢失,而request范围属性,在关闭网页后,任何一个非forward跳转页中均获取不到,因为它的生命周期只在一次forward之间,断开这次forward,其属性会丢失掉。

 

 

 

 

0 0