计数器的实现

## n SESSION（会话）技术

HTTP协议是无状态的，即信息无法通过HTTP协议本身进传递。为了跟踪用户的操作状态，JSP使用一个叫HttpSession的对象实现同样的功能。

HttpSession 是一个建立在cookies 和URL-rewriting上的高质量的界面。Session的信息保存在服务器端，Session的id保存在客户机的cookie中。

事实上，在许多服务器上，如果浏览器支持的话它们就使用cookies，但是如果不支持或废除了的话就自动转化为URL-rewriting，session自动为每个流程提供了方便地存储信息的方法。

Session一般在服务器上设置了一个30分钟的过期时间，当客户停止活动后自动失效。Session 中保存和检索的信息不能是基本数据类型如 int，double等，而必须是java的相应的对象,如Integer，Double。

## n HttpSession API

getId()，此方法返回唯一的标识，这些标识为每个session而产生。当只有一个单一的值与一个session联合时，或当日志信息与先前的sessions有关时，它被当作键名用。

GetCreationTime()，返回session被创建的时间。最小单位为千分之一秒。为得到一个对打印输出很有用的值，可将此值传给Date constructor 或者GregorianCalendar的方法setTimeInMillis。

GetLastAccessedTime()，返回session最后被客户发送的时间。最小单位为千分之一秒。

GetMaxInactiveInterval()，返回总时间（秒），负值表示session永远不会超时。

getAttribute()，取一个session相联系的信息。（在jsp1.0中为 getValue）

Integer item = (Integer) session.getAttrobute("item")，检索出session的值并转化为整型

setAttribute()，提供一个关键词和一个值。会替换掉任何以前的值。(在jsp1.0中为putValue)

session.setAttribute("ItemValue", itemName)，ItemValue不能是简单类型。

HttpSession接口提供了存储和返回标准会话属性的方法。标准会话属性如会话标识符、应用数据等，都以“名字-值”对的形式保存在服务器端。也就是说，HttpSession接口提供了一种把对象保存到内存、在同一用户的后继请求中提取这些对象的标准办法。在会话中保存数据的方法是setAttribute(String s, Object o)，从会话提取原来所保存对象的方法是getAttribute(String s)。

在服务器端，每当新用户请求一个使用了HttpSession对象的JSP页面，Servlet/JSP容器除了发回应答页面之外，它还要向浏览器发送一个特殊的数字。这个特殊的数字称为“会话标识符”，它是一个唯一的用户标识符。此后，HttpSession对象就驻留在内存之中(这当然是在服务器端)，等待同一用户返回时再次调用它的方法。

在客户端，浏览器保存会话标识符，并在每一个后继请求中把这个会话标识符发送给服务器。会话标识符告诉JSP容器当前请求不是用户发出的第一个请求，服务器以前已经为该用户创建了HttpSession对象。此时，JSP容器不再为用户创建新的HttpSession对象，而是寻找具有相同会话标识符的HttpSession对象，然后建立该HttpSession对象和当前请求的关联。

会话标识符以Cookie的形式在服务器和浏览器之间传送，标准会话属性在服务器端也是以会话的形式存在的，并且这个Cookie的生命周期只是临时的，即会话结束后就自动消失，没有为它指定固定的生命周期，因此有人说session是基于Cookie的技术。另外，如果客户端不支持Cookie，运用url重写机制来保证会话标识符传回服务器。

还有一点，session不像Cookie那样拥有路径访问的问题。session对应的是窗口，只要是同一个客户端或者是存在父子关系的多个客户端，同一个application下的servlet/JSP可以共享同一个session。当然，session和窗口的对应关系也是受时间限制的，至于多长时间，可以在服务器的conf/web.xml中配置30

实例代码:

#### 1.设置session 和 显示session

1. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

2. resp.setContentType("text/html");

3. PrintWriter out=resp.getWriter();

4. //String title="Session Tracking Example";

5. HttpSession session=req.getSession(true);//如果没有该session，则自动创建一个新的

6. String heading;

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

8. if(accessCount==null){

9. accessCount=new Integer(0);

10. heading="Welcome, NewComer!";

11. }else{

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

13. heading="Welcome,back!";

14. }

15. session.setAttribute("accessCount", accessCount);

16. out.println(""

17. +"\n"

18. +"

19.

20. "

21. +heading+"

22. \n"

23. +"

24. Information On Your Session:

25. \n"

26. +"\n"

27. +" \n"+" id\n"+" "+session.getId()+"\n"

28. +"

29. \n"+" CreatTime\n"+" "

30. +new Date(session.getCreationTime())+"\n"

31. +"

32. \n"+" Time Of Last Access\n"+" "

33. +new Date(session.getLastAccessedTime())+"\n"

34. +"

35. \n"+" Number Of Prious Access\n"+" "

36. +accessCount+"\n"+"

37. \n"+"");

38. }

39.

#### 2.URL重写

1. protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

2. resp.setContentType("text/html");

3. PrintWriter out=resp.getWriter();

4. HttpSession session=req.getSession(true);

5. out.println(""

6. +"\n"

7. +"Session ID: "+session.getId()+"

8. "

9. +"from URL? : "+req.isRequestedSessionIdFromURL()+"

10. "

11. +"from Cookie? : "+req.isRequestedSessionIdFromCookie()+"

12. "

13. +"test"//重写URL：encodeURL(),如果浏览器的cookie没有禁掉，则这句话没有对 req.getRequestURL().toString()作任何处理，还是保持这个字符串的原样；如果cookie被禁掉了,则在字符串的后面加上一字符串"；"+session ID

14. +"test"

15. +"");

16. }