servlet 笔记

本文详细介绍了Servlet的基础知识,包括目录结构、Servlet生命周期、开发过程、部署步骤以及Servlet与HTTP方法的关系。重点讨论了Servlet的doGet和doPost方法,以及如何处理请求参数,特别是使用Enumeration遍历请求参数。此外,还探讨了Session的原理、管理和跟踪,强调了在客户端禁用Cookie时使用URL重写的重要性。最后提到了Application(ServletContext)的作用及其在全局数据共享中的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1.   servlet的目录结构(以tomcat为例)。

 

所有application工程需要放到tomcat的webapps文件下,并建立如下文件,例子中webapps的名字为my。

³ Web App 下面必须要有WEB-INF目录,可以有META-INF目录。

² WEB-INF(下面必须有libclasses文件夹以及web.xml文件)

± web.xml为该web app的配置文件

± lib 该文件夹下存放当前这个web app用到的库文件(jar包)。tomcat会自动加载。要注意这个lib是只对这个webapp有效的。

± classes存放编译好的servlet class文件(可以有子目录,作为包的结构)。

² META-INF (和WEB-INF同级)

± 存放该web app的上下文信息,符合J2EE标准

 

目录层次如下:

 

Web Application可以直接放在webapp下面,也可以通过配置文件指定到其他目录 <host>里面

² <Context path=“/虚拟路径名“ docBase=”目录位置"debug="0" reloadable="true"/>

 

2.   什么是servlet和servlet的开发过程。

Servlet本身是一个接口,来自于javax.servlet。有两个子类:GenericServlet (抽象类),和HttpServlet。而HttpServlet又继承了GenericServlet,并且实现序列化接口。HttpServlet才是我们正式使用的类。

在使用HttpServlet类的时候, 最常用的两个方法是doGet和doPost。这两个都是默认由service方法来自动调用了。service方法不用重写。 通常我们都是重写doGet和doPost。

 

Get方式和post方式有什么区别?

get方式:在浏览器栏敲入地址。

post方式:从form中提交,并且form指明了是使用post方式。

 

在HttpServlet类的doxxx方法都有两个参数,分别是request和response。

Request是客户机对服务器的请求。所以服务器向从客户机里读东西,都是从request里面拿。

Response是服务器对客户机的相应。所以服务器向对客户机写东西,都是写到response里面。

 

在eclipse当中编译servlet程序,必须引入C:\apache-tomcat-6.0.14\lib下面的jsp-api.jar包。然后才可以再java程序当中引入javax.servlet.*;

 

 

在一个tomcat的执行过程中:service方法是默认会调用的,用来去执行各个doxxx方法。

注意在HttpServlet类下面有两个service方法,分别是:

protected void

service(HttpServletRequest req, HttpServletResponse resp)

void

service(ServletRequest req, ServletResponse res)

 

没有protected 的service方法是HttpServlet实现的父类的接口,也就是说,tomcat先调用这个没有protected的方法,然后这个没有proteced的方法会去调用有protected的service方法。

有protected的service方法是专门对应http协议的方法。所以他可以去专门去处理相应的doXXX(doGet,doPost等等)方法。具体调用doXXX什么方法,在于客户端的请求是以什么方式过来的。

 

tips:不要把代码考来考去的,只放到一个地方,修改的时候就方便。宁愿用方法调用的方式去执行。

 

 

3.   Servlet的部署

第一步,把在eclipse当中编译好的class文件,复制到C:\apache-tomcat-6.0.14\webapps\my\WEB-INF\classes目录下。

 

第二步,编辑相应的webapp的对应的web.xml,本例中是C:\apache-tomcat-6.0.14\webapps\my\WEB-INF下的web.xml。对每一个servlet,加入servlet和servletmapping标签。

 

<?xmlversion="1.0" encoding="ISO-8859-1"?>

<web-appxmlns="http://java.sun.com/xml/ns/javaee"

  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

   xsi:schemaLocation="http://java.sun.com/xml/ns/javaeehttp://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"

   version="2.5">

   

    <servlet>

       <servlet-name>myfirstservlet</servlet-name>

       <servlet-class>HelloWorldServlet</servlet-class>

    </servlet>

    <servlet-mapping>

       <servlet-name>myfirstservlet</servlet-name>

       <url-pattern>/HelloWorldServlet</url-pattern>

    </servlet-mapping>

   

</web-app>

 

<servlet-name>myfirstservlet</servlet-name>是告诉tomcat这个servlet的名字,可以自己随便定义。<servlet-class>HelloWorldServlet</servlet-class>是放在C:\apache-tomcat-6.0.14\webapps\my\WEB-INF\classes下面那个class文件的名字。

 

servlet和servletmapping是配对的,也就是说,servletmapping通过和servlet描述同样的<servlet-name>来设定对于该servlet的URL地址。注意<url-pattern> </url-pattern>当中放入的连接是相对于webapp而言的,也就是说,与html当中不一样,在这里,/代表当前的webapp,访问的是webapp的根目录,而不是tomcat的根目录。

 

带有包的servlet的部署。

在如果class文件是有包的层级结构的,在C:\apache-tomcat-6.0.14\webapps\my\WEB-INF\classes当中也要加入相应的层次结构(必须是用全名)。把myfirstservlet.class放到C:\apache-tomcat-6.0.14\webapps\my\WEB-INF\classes\com\bjsxt\test\目录下。

同时修改C:\apache-tomcat-6.0.14\webapps\my\WEB-INF下的web.xml,加入servlet和servletmapping标签。

Servlet标签的写法:

    <servlet>

        <servlet-name>com.bjsxt.test.myfirstservlet</servlet-name>

       <servlet-class>HelloWorldServlet</servlet-class>

    </servlet>

才可以正常访问。

 

为了方便修改tomcat当中的信息(比如配置xml等),在C:\apache-tomcat-6.0.14\conf下修改context.xml,把第一行改成<Context reloadable="true">,那么tomcat就会检查我们对tomcat的改动,每个1分钟reload一次。

 

在tomcat容器的情况下,注意在地址栏当中输入的地址,必须区分大小写,不然就会出现访问不到的情况。

 

默认情况下,中文没有办法在tomcat里面显示?

解决方法是:在打印流把字符集设成GBK。

代码如下:resp.setContentType(“text/html; charset=gbk”);

 

 

4.     Serlvet生命全过程
第一步,加载 ClassLoader
第二步,实例化 new 在客户端的第一次请求到达的时候。而且只new一遍。
第三步,初始化 init(ServletConfig) 也只执行一次。
第四步,处理请求 service doGet doPost
第五步,退出服务 destroy()

其核心在于整个生命周期当中,只有一个servlet对象

 

API中的过程:
init()//只执行一次, 第一次初始化的时候
public void init(ServletConfig config)throws ServletException
 
service()
public void service(ServletRequest req,ServletResponse res) throws ServletException, java.io.IOException
 
destroy()//webapp 退出的时候
public void destroy()

 

关于为什么有两个init()方法?

有两个init(),一个是不带参数的init(),另外一个是init(ServletConfig config),其实就只有一个。不带参数的init()是用来方便程序员重写的。

 

5.   servlet从上一个页面取参数的方式。

通过在doxxx方法里面的request.getParameter("param1")方法。

 

页面如下:

<formid="form1" name="form1" method="post"action="ThreeParams">

  <table width="343"border="1">

    <tr>

      <tdwidth="92">param1</td>

      <td width="94"><inputname="param1" type="text" id="param1" />      </td>

    </tr>

    <tr>

      <td>param2</td>

      <td><label>

        <input name="param2"type="text" id="param2" />

      </label></td>

    </tr>

    <tr>

      <td>param3</td>

      <td><inputname="param3" type="text" id="param3"/></td>

    </tr>

   <tr>

      <td>&nbsp;</td>

      <td><label>

        <input type="submit"value="提交" />

      </label></td>

    </tr>

  </table>

  </form>

 

servlet如下,要注意是的中文乱码问题:

import javax.servlet.*;

import javax.servlet.http.*;

 

import java.io.*;

 

publicclass ThreeParams extends HttpServlet{

 

    privatestaticfinallongserialVersionUID = 1L;

 

    @Override

    protectedvoid doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException,IOException {

       response.setContentType("text/html;charset=GBK");

       //解决post方式提交内容的乱码

       //一定要写在存取第一个参数之前

       request.setCharacterEncoding("GBK");

      

       //解决get方式乱码问题:在server.xml当中,connector标签-->URIEncoding="GBK"

      

       PrintWriter out = response.getWriter();

       out.println(request.getParameter("param1"));

       out.println("<br>");

       out.println(request.getParameter("param2"));

       out.println("<br>");

       out.println(request.getParameter("param3"));

       out.println("<br>");

       System.out.println("indoGet");

    }

 

    @Override

    protectedvoid doPost(HttpServletRequest request, HttpServletResponseresponse) throws ServletException, IOException {

      

       System.out.println("indoPost");

       doGet(request, response);

    }

}

 

参数传递的是通过html文件的当中的name来确定参数的名称,而不是id,这点要注意。

 

5.1对于多参数的页面传递:

有两种方式遍历:

一个是Enumeration

要注意!这里的Enumeration不是枚举的类型,而是一个容器便利器。Enumeration是一个接口,来自java.util。而且是一个从jdk1.0就有的接口。其功能和Iterator功能是重复的,而且已经被Iterator所取代。可以认为Enumeration就是一个已经废弃的Iterator

而,Emum才是真正的枚举类型。,而且是一个类。来自java.lang。是一个从jdk1.5才有的类。其功能才是真正的枚举。

 

 

import java.io.*;

import javax.servlet.*;

import javax.servlet.http.*;

import java.util.*;

 

//获取所有的参数

 

publicclass ShowParameters extends HttpServlet {

    publicvoid doGet(HttpServletRequest request, HttpServletResponse response)

           throws ServletException, IOException {

       response.setContentType("text/html;charset=gb2312");

       PrintWriter out = response.getWriter();

       String title = "Reading AllRequest Parameters";

       out.println("<html><head><title>读取所有参数</title></head>"

              + "<BODYBGCOLOR='#FDF5E6'>\n" + "<H1 ALIGN=CENTER>" + title

              + "</H1>\n" + "<TABLEBORDER=1 ALIGN=CENTER>\n"

              + "<TRBGCOLOR=\"#FFAD00\">\n"

              + "<TH>ParameterName<TH>Parameter Value(s)");

      

       //通过Eumeration容器遍历器,类似Iterator方式

       Enumeration paramNames = request.getParameterNames();

       while (paramNames.hasMoreElements()) {

           String paramName =(String) paramNames.nextElement();

           out.print("<TR><TD>" + paramName + "\n<TD>");

           //同一个名字的参数,但是有不同的值。通过同样的一个名字,取出多个值。

           String[] paramValues = request.getParameterValues(paramName);

          

           if (paramValues.length == 1) {

              String paramValue = paramValues[0];

              if (paramValue.length() == 0)

                  out.println("<I>No Value</I>");

              else

                  out.println(paramValue);

           } else {

              out.println("<UL>");

              for (int i = 0; i < paramValues.length; i++) {

                  out.println("<LI>" + paramValues[i]);

              }

              out.println("</UL>");

           }

       }

       out.println("</TABLE>\n</BODY></HTML>");

    }

 

    publicvoid doPost(HttpServletRequest request, HttpServletResponseresponse)

           throws ServletException, IOException {

       doGet(request, response);

    }

}

 

另外一个方式是使用map接口。

 

import java.io.*;

import javax.servlet.*;

import javax.servlet.http.*;

import java.util.*;

 

//获取所有的参数

 

publicclass ShowParametersMap extends HttpServlet {

    publicvoid doGet(HttpServletRequest request, HttpServletResponseresponse)

           throws ServletException, IOException {

       response.setContentType("text/html;charset=gb2312");

       PrintWriter out = response.getWriter();

       String title = "Reading AllRequest Parameters";

       out.println("<html><head><title>读取所有参数</title></head>"

              + "<BODYBGCOLOR='#FDF5E6'>\n" + "<H1 ALIGN=CENTER>" + title

              + "</H1>\n" + "<TABLEBORDER=1 ALIGN=CENTER>\n"

              + "<TRBGCOLOR=\"#FFAD00\">\n"

              + "<TH>ParameterName<TH>Parameter Value(s)");

      

       //不用枚举,用map,注意采用的方法是request.getParamterMap()获取的是字符串(key+字符串数组(value

       Map<String, String[]> paramMap =request.getParameterMap();

      

       Set<Map.Entry<String, String[]>> entries =paramMap.entrySet();

       //map不能用iterator,所以把内容放到set里面。

       for(Iterator<Map.Entry<String, String[]>> it =entries.iterator(); it.hasNext(); ) {

           Map.Entry<String, String[]> entry = it.next();

           String paramName = entry.getKey();

           out.print("<TR><TD>" + paramName + "\n<TD>");

           String[] paramValues = entry.getValue();

           if (paramValues.length == 1) {

              String paramValue = paramValues[0];

              if (paramValue.length() == 0)

                  out.println("<I>No Value</I>");

              else

                  out.println(paramValue);

           } else {

              out.println("<UL>");

              for (int i = 0; i < paramValues.length; i++) {

                  out.println("<LI>" + paramValues[i]);

              }

              out.println("</UL>");

           }

       }

       out.println("</TABLE>\n</BODY></HTML>");

    }

 

    publicvoid doPost(HttpServletRequest request, HttpServletResponseresponse)

           throws ServletException, IOException {

       doGet(request, response);

    }

}

 

6.   COOKIE的用法

6.1 HTTP协议的特点:

由于HTTP本身是无连接性的:也就是说和客户端的连接断掉了以后,不保存任何来自客户端的信息。那么在客户端再次访问的时候,服务器将没有办法找到任何来自客户端的信息,也就是说,在客户端再次访问的时候,根本就没有上次访问的任何信息。

6. 2 COOKIE是什么?

1:服务器可以向客户端写信息,也就是Cookie。

2:cookie只能是文本内容(不可以是exe,也不可以是图片),并且最大只能是4k。

3:客户端可以阻止服务器写入:浏览器可以把cookie禁用。所以对服务器而言,Cookie当中不应该放有核心的业务逻辑。一般是可有可无的内容。

4:服务器在读取cookie的时候,只能拿自己输入webapp写入的东西。也就是说,服务器只能拿自己在客户端上写入的cookie,而不能去拿别的网站的信息。

5:Cookie分为两种

       第一种叫session cookie,属于窗口/子窗口(放在内存中的),也就是说当前浏览器窗口关闭就消失。但是从当前窗口打开的窗口,是可以看到session cookie的。

       第二种叫persistent cookie,属于文本(有生命周期的),可以设定它的存在时间。

 

6:一个servlet/jsp设置的cookies能够被同一个路径下面或者子路径下面的servlet/jsp读出来。 反过来,父路径不能访问在子路径的设置的cookies.

 

要注意:类似于map, Cookie当中存储的也是键值对。注意,这里所说的路径是指在web.xml当中设置的路径<url-pattern>/HelloWorldServlet</url-pattern>,而不是物理文件在硬盘上存储的位置(实际上,物理文件的层次结构代表的是包的结构)。

cookie写到客户端用response.addCookie(cookie),从客户端读cookierequest.getCookies()

1.SetCookies

import java.io.*;

import javax.servlet.*;

import javax.servlet.http.*;

 

publicclass SetCookies extends HttpServlet {

    publicvoid doGet(HttpServletRequest request, HttpServletResponseresponse)

           throws ServletException, IOException {

 

       for (int i = 0; i < 3; i++) {

           // Default maxAgeis -1, indicating cookie applies only to current browsing session.

           //通过tomcat new出一个cookie,第一个参数是cookie的名字,第二个参数是cookie的值。

           Cookie cookie = new Cookie("Session-Cookie-" + i, "Cookie-Value-S" + i);

           //cookie的内容写到客户端。

           response.addCookie(cookie);

          

           //是Persistent类型的cookie

           cookie = new Cookie("Persistent-Cookie-" + i, "Cookie-Value-P" + i);

           // Cookie isvalid for an hour, regardless of whether user quits browser, reboots computer,or whatever.

           //cookie存在的时间,以秒为单位,这里就是1个小时。退出浏览器,重启电脑,都对不对这个cookie的存活时间造成影响。

           cookie.setMaxAge(3600);

           response.addCookie(cookie);

       }

       response.setContentType("text/html;charset=gb2312");

       PrintWriter out = response.getWriter();

       out.println("<html><head><title>设置Cookie</title></head>"

              + "<BODY>\n"

              + "<H1ALIGN=\"CENTER\">"

              + "设置Cookie" + "</H1>\n"

              + "6Cookie\n"

              + "<AHREF=\"ShowCookies\">\n"

              + "查看</A>.\n"

              + "</BODY></HTML>");

    }

}

 

2.ShowCookies

 

import java.io.*;

import javax.servlet.*;

import javax.servlet.http.*;

 

//读取客户端的Cookie

 

publicclass ShowCookies extends HttpServlet {

  publicvoid doGet(HttpServletRequest request,

                    HttpServletResponseresponse)

      throws ServletException, IOException{

    response.setContentType("text/html;charset=gb2312");

    PrintWriter out = response.getWriter();

    String title = "Active Cookies";

    out.println("<html><head><title>获取客户端Cookie</title></head>" +

                "<BODY BGCOLOR=\"#FDF5E6\">\n" +

                "<H1 ALIGN=\"CENTER\">" + title + "</H1>\n" +

                "<TABLE BORDER=1 ALIGN=\"CENTER\">\n" +

                "<TR BGCOLOR=\"#FFAD00\">\n" +

                <TH>CookieName\n" +

                <TH>Cookie Value");

    //得到来自于客户端的cookie,放到一个数组里面

    Cookie[] cookies = request.getCookies();

    if (cookies != null) {

      Cookie cookie;

      for(int i=0; i<cookies.length; i++) {

        cookie = cookies[i];

        out.println("<TR>\n" +

                  //获取cookie的键

                    <TD>" + cookie.getName() + "</TD>\n" +

                  //获取cookie的值

                    <TD>" + cookie.getValue() + "</TD></TR>\n" );

      }

    }

    out.println("</TABLE></BODY></HTML>");

  }

}

7.   Session的用法:

和cookie最大的区别在于session是放在服务器端的。当客户端第一次访问服务器的时候,服务器上采用对每个不同的客户生成ID的方式来区分不同客户对象,同时也会把ID的信息通过cookie写到客户端去。也就说,使用session的时候,依然是要使用cookie的。当一个新的客户端放过服务器的时候,服务器首先检查该客户端的ID,如果有服务器有相应的ID于之相配对,就是说明是老客户,已经访问过该服务器。如果没有ID就马上创建一个为其下次访问做准备,同时也会把ID的信息通过cookie写到客户端去。

 

Session就是在某段时间一连串客户端与服务器端的“交易”。其实建立一个session就是服务器生成属于一个客户端的session的ID号。

 

在Jsp/Servlet中,Seesion的两种实现方式:

1.使用cookie实现。

2.如果浏览器不支持Cookie,可以通过URL重写来实现,就是将一些额外数据追加到表示会话的每个URL末尾,服务器在该标示符与其存储的有关的该会话的数据之间建立关联。如hello.jsp?jsessionid=1234

 

可以通过程序来终止一个session。如果客户端在一定时间内没有操作,服务器会自动终止session。

 

不象Cookie,Session没有路径访问的问题:

同一个webapp下的servlet/jsp可以在一个客户端窗口,共享同一个session. 也就是说只要在同一个webapp,无论访问什么地方,都可以访问的到。

 

getRequestedSessionId():返回随客户端请求到来的会话ID。可能与当前的会话ID相同,也可能不同。

getSession(booleanisNew):如果会话已经存在,则返回一个HttpSession,如果不存在并且isNew为true,则会新建一个HttpSession.

isRequestedSessionIdFromCookie():当前的Session ID如果是从Cookie获得,为true

isRequestedSessionIdFromURL():当前Session ID如果是由URL获得,为true

isRequestedSessionIdValid():如果客户端的会话ID代表的是有效会话,则返回true。否则(比如,会话过期或根本不存在),返回false

 

HttpSession的常用方法

getAttributeNames()/getAttribute()

getCreateTime()

getId()

getMaxInactiveInterval()

invalidate()

isNew()

setAttribute()

setMaxInactivateInterval()

 

ShowSession

import java.io.*;

import javax.servlet.*;

import javax.servlet.http.*;

import java.net.*;

import java.util.*;

 

//Session追踪

 

publicclass ShowSession extends HttpServlet {

    publicvoid doGet(HttpServletRequest request, HttpServletResponseresponse)

           throws ServletException, IOException {

       response.setContentType("text/html");

       PrintWriter out = response.getWriter();

       String title = "SessionTracking Example";

      

       //得到客户端对应的session对象,如果找不到(客户端第一次访问),就创建一个。

       //可以得到一个session对象的引用。

       HttpSession session = request.getSession(true);

       String heading;

       // Use getAttribute instead ofgetValue in version 2.2.

//取出"accessCount",返回的是"accessCount"的对象(object类型)。

       Integer accessCount = (Integer) session.getAttribute("accessCount");

       if (accessCount == null) {

           accessCount = new Integer(0);

           heading = "Welcome,Newcomer";

       } else {

           heading = "Welcome Back";

           accessCount = new Integer(accessCount.intValue() + 1);

       }

       // Use setAttribute insteadof putValue in version 2.2.

    //session就是一个篮子,可以往里面放东西。"accessCount"是对象的引用。AccessCount是值。

       session.setAttribute("accessCount", accessCount);

 

       out.println("<html><head><title>Session追踪</title></head>"

              + "<BODYBGCOLOR=\"#FDF5E6\">\n" + "<H1ALIGN=\"CENTER\">"

              + heading + "</H1>\n"

              + "<H2>Informationon Your Session:</H2>\n"

              + "<TABLEBORDER=1 ALIGN=\"CENTER\">\n"

              + "<TRBGCOLOR=\"#FFAD00\">\n" + <TH>Info Type<TH>Value\n"

              + "<TR>\n" + <TD>ID\n" + <TD>" + session.getId()+ "\n"

              + "<TR>\n" + <TD>Creation Time\n" + <TD>"

              //得到session对象的创建时间

              + new Date(session.getCreationTime()) + "\n" + "<TR>\n"

              + <TD>Time of Last Access\n" + <TD>"

              //得到session对象的最后访问时间

              + new Date(session.getLastAccessedTime()) + "\n" + "<TR>\n"

              + <TD>Number of Previous Accesses\n" + <TD>"

              + accessCount + "\n" + "</TABLE>\n" + "</BODY></HTML>");

 

    }

 

    /**HandleGETandPOSTrequestsidentically.*/

 

    publicvoid doPost(HttpServletRequest request, HttpServletResponseresponse)

           throws ServletException, IOException {

       doGet(request, response);

    }

}

 

在客户端把cookie禁掉的情况下,session将无法正常工作(因为没有办法把ID写过去),每次都创建新的session对象,也就是每次都创建新的ID, 这个时候就要采取URL重写的方式来实现session。函数为response.encodeURL()。它的功能是:

1.转码,中文乱码问题。

2.URL后面加入SessionId

如果cookie没有被禁掉,就是显示当前servlet的URL地址。

如果cookie被禁掉,这个sessionID就会加入到这个字符串当中。那么通过这种URL重写的方式,服务器希望往客户端上写的sessionID就可以被读取到,服务器就不会每次都重新分配一个新的sessionID,在浏览器窗口没有被关闭的期间,这个sessionID一直有效。

 

1. SessionInfoServlet

import javax.servlet.*;

import javax.servlet.http.*;

import java.io.*;

/**

 *用于演示ServletAPI中的Session管理机制

 */

publicclass SessionInfoServlet extends HttpServlet

{

  /**

   *BuildsanHTMLdocumentcontainingsessioninformationand

   *returnsittotheclient.

   */

  publicvoid doGet(HttpServletRequest request,

    HttpServletResponse response) throws ServletException,

    IOException

  {

    //getcurrent session or, if necessary, create a new one

    HttpSession mySession = request.getSession(true);

 

    //MIMEtype to return is HTML

    response.setContentType("text/html");

 

    //get ahandle to the output stream

    PrintWriter out = response.getWriter();

 

    //generateHTML document

    out.println("<HTML>");

    out.println("<HEAD>");

    out.println("<TITLE>Session Info Servlet</TITLE>");

    out.println("</HEAD>");

    out.println("<BODY>");

    out.println("<H3>Session Information</H3>");

    out.println("New Session: " +mySession.isNew());

    out.println("<BR>Session ID: " + mySession.getId());

    out.println("<BR>Session Creation Time: " +

      newjava.util.Date(mySession.getCreationTime()));

    out.println("<BR>Session Last Accessed Time: " +

      newjava.util.Date(mySession.getLastAccessedTime()));

 

    out.println("<H3>Request Information</H3>");

    out.println("Session ID from Request: " +

        //从客户端带过来的sessionID

      request.getRequestedSessionId());

    out.println("<BR>Session ID via Cookie: " +

        //sessionID是不是从cookie取过来

     request.isRequestedSessionIdFromCookie());

    out.println("<BR>Session ID via rewritten URL: " +

        //sessionID是不是从地址栏取过来

      request.isRequestedSessionIdFromURL());

    out.println("<BR>Valid Session ID: " +

        //sessionID是不是合法有效的

      request.isRequestedSessionIdValid());

 

    out.println("</BODY></HTML>");

 

    out.close(); //close output stream

  }

 

 

  /**

   *Returnsabriefdescriptionofthisservlet.

   *

   *@returnBriefdescriptionofservlet

   */

  public String getServletInfo()

  {

    return"Servlet returns session information.";

  }

}

 

2. URLSession

 

import java.io.*;

import javax.servlet.*;

import javax.servlet.http.*;

import java.net.*;

import java.util.*;

 

//Session追踪

 

publicclass URLSession extends HttpServlet {

    publicvoid doGet(HttpServletRequest request, HttpServletResponse response)

           throws ServletException, IOException {

       response.setContentType("text/html");

       PrintWriter out = response.getWriter();

      

       HttpSession session = request.getSession(true);

 

       out.println("<html><head><title>Session追踪</title></head>"

              + "<BODY>\n"

              + "sessionid:" + session.getId() + "<br>"

              + "fromurl:" + request.isRequestedSessionIdFromURL() + "<br>"

              + "from cookie:" + request.isRequestedSessionIdFromCookie() + "<br>"

              //得到当前访问的servletURL地址

+ "<ahref=" +response.encodeURL(request.getRequestURL().toString()) +">test</a>"

              + "</BODY></HTML>");

 

    }

 

    /**HandleGETandPOSTrequestsidentically.*/

 

    publicvoid doPost(HttpServletRequest request, HttpServletResponseresponse)

           throws ServletException, IOException {

       doGet(request, response);

    }

}

 

response.encodeURL()和response.encodeUrl()问题。

注意用大写的这个方法,小写的是过去的版本。做事严谨起见,为了防止客户端禁止cookie,一般采用URL重写的方式来对付session问题。

 

Session总结:

session的实质就是在服务器的一块内存(存key-value)

每个sesion和客户端窗口对应(子窗口)(通过客户端和服务器有对应独一无二的SessionID

客户端向服务器端发送SessionID的时候两种方式:

cookie(内存cookie) 浏览器禁掉cookie,就不能使用cookie实现的session

rewritten URL.如果想安全的使用session(不论客户端是否禁止cookie),只能使用URL重写(大大增加编程负担),所以很多网站要求客户端打开cookie.

 

 

 

 

Cookie

session

存储在客户端

存储在服务器端

两种类型

l  有声明周期

l  无声明周期

两种实现方式

l  依赖于cookie

l  url重写

父路径不能访问子路径的cookie

同一个session的窗口共享一个session

典型应用:

l  3个月不用再登陆

l  购物车(http://www.china-pub.com/)

典型应用:

l  用户登陆

l  购物车也可以用session实现。·

不可靠

可靠

 

8.   Application:

用于保存整webapp的声明周期内都可以访问的数据,在API中表现为servletContext。这是指servlet的运行环境,怎么和运行环境打交道,servletContext是比session还大的篮子,一个webapp下面所有的servlet访问同一个servletContext。session是对一个客户端有效的,servletContext是对所有的客户端都有效的。所以servletContext可以用来做页面的访问次数计数器。servletContext是通过HttpServlet的getServletContext来获取的。通过servletContext的get/setAttribute方法取得设置属性。

 

1. TestServletContext

import javax.servlet.http.*;

import javax.servlet.*;

 

import java.io.*;

import java.util.Date;

 

publicclass TestServletContext extends HttpServlet {

 

    @Override

    protectedvoid doGet(HttpServletRequest request,

           HttpServletResponse response) throws ServletException, IOException{

       response.setContentType("text/html;charset=gb2312");

       PrintWriter out = response.getWriter();

      

       //得到servlet的上下文,是指servlet的运行环境,怎么和运行环境打交道。

       ServletContext application = this.getServletContext();

      

       //application是比session还大的篮子,一个webapp下面所有的servlet访问同一个application

       //session是对一个客户端有效的,application是对所有的servlet有效的。

       Integer accessCount = (Integer) application.getAttribute("accessCount");

       if (accessCount == null) {

           accessCount = new Integer(0);

          

       } else {

          

           accessCount = new Integer(accessCount.intValue() + 1);

       }

       // Use setAttribute insteadof putValue in version 2.2.

       application.setAttribute("accessCount", accessCount);

 

       out.println("<html><head><title>Session追踪</title></head>"

              + "<BODYBGCOLOR=\"#FDF5E6\">\n" + "<H1ALIGN=\"CENTER\">"

              + accessCount + "\n" + "</TABLE>\n" + "</BODY></HTML>"

              + "</H1>\n");

             

 

    }

 

}

 

9.   Servlet连接数据库 学习完数据库再补充

拷贝数据库驱动的jar包到apache-tomcat-6.0.14\webapps\Test\WEB-INF\lib文件夹

确认数据库已经启动

用户名、密码应该正确

 

Tips:在ServletJSP当中尽量不要用成员变量。因为多个线程客户端公用的是同一个对象的同一个成员标量。可能出现不可预知的问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值