配色: 字号:
JavaWeb——Session
2016-09-02 | 阅:  转:  |  分享 
  
JavaWeb——Session



一、Session简单介绍



在WEB开发中,服务器可以为每个用户浏览器创建一个会话对象(session对象),注意:一个浏览器独占一个session对象(默认情况下)。因此,在需要保存用户数据时,服务器程序可以把用户数据写到用户浏览器独占的session中,当用户使用浏览器访问其它程序时,其它程序可以从用户的session中取出该用户的数据,为用户服务。



二、Session和Cookie的主要区别



Cookie是把用户的数据写给用户的浏览器。

Session技术把用户的数据写到用户独占的session中。

Session对象由服务器创建,开发人员可以调用request对象的getSession方法得到session对象。

三、session实现原理



3.1、服务器是如何实现一个session为一个用户浏览器服务的?



服务器创建session出来后,会把session的id号,以cookie的形式回写给客户机,这样,只要客户机的浏览器不关,再去访问服务器时,都会带着session的id号去,服务器发现客户机浏览器带sessionid过来了,就会使用内存中与之对应的session为之服务。可以用如下的代码证明:



复制代码

1packagexdp.gacl.session;

2

3importjava.io.IOException;

4importjavax.servlet.ServletException;

5importjavax.servlet.http.HttpServlet;

6importjavax.servlet.http.HttpServletRequest;

7importjavax.servlet.http.HttpServletResponse;

8importjavax.servlet.http.HttpSession;

9

10publicclassSessionDemo1extendsHttpServlet{

11

12publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)

13throwsServletException,IOException{

14

15response.setCharacterEncoding("UTF=8");

16response.setContentType("text/html;charset=UTF-8");

17//使用request对象的getSession()获取session,如果session不存在则创建一个

18HttpSessionsession=request.getSession();

19//将数据存储到session中

20session.setAttribute("data","孤傲苍狼");

21//获取session的Id

22StringsessionId=session.getId();

23//判断session是不是新创建的

24if(session.isNew()){

25response.getWriter().print("session创建成功,session的id是:"+sessionId);

26}else{

27response.getWriter().print("服务器已经存在该session了,session的id是:"+sessionId);

28}

29}

30

31publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)

32throwsServletException,IOException{

33doGet(request,response);

34}

35}

复制代码

第一次访问时,服务器会创建一个新的sesion,并且把session的Id以cookie的形式发送给客户端浏览器,如下图所示:







点击刷新按钮,再次请求服务器,此时就可以看到浏览器再请求服务器时,会把存储到cookie中的session的Id一起传递到服务器端了,如下图所示:







我猜想request.getSession()方法内部新创建了Session之后一定是做了如下的处理



复制代码

1//获取session的Id

2StringsessionId=session.getId();

3//将session的Id存储到名字为JSESSIONID的cookie中

4Cookiecookie=newCookie("JSESSIONID",sessionId);

5//设置cookie的有效路径

6cookie.setPath(request.getContextPath());

7response.addCookie(cookie);

复制代码

四、浏览器禁用Cookie后的session处理



4.1、IE8禁用cookie



工具->internet选项->隐私->设置->将滑轴拉到最顶上(阻止所有cookies)





4.2、解决方案:URL重写



response.encodeRedirectURL(java.lang.Stringurl)用于对sendRedirect方法后的url地址进行重写。

response.encodeURL(java.lang.Stringurl)用于对表单action和超链接的url地址进行重写



4.3、范例:禁用Cookie后servlet共享Session中的数据



IndexServlet



复制代码

1packagexdp.gacl.session;

2

3importjava.io.IOException;

4importjava.io.PrintWriter;

5importjava.util.LinkedHashMap;

6importjava.util.Map;

7importjava.util.Set;

8importjavax.servlet.ServletException;

9importjavax.servlet.http.HttpServlet;

10importjavax.servlet.http.HttpServletRequest;

11importjavax.servlet.http.HttpServletResponse;

12

13//首页:列出所有书

14publicclassIndexServletextendsHttpServlet{

15

16publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)

17throwsServletException,IOException{

18

19response.setContentType("text/html;charset=UTF-8");

20PrintWriterout=response.getWriter();

21//创建Session

22request.getSession();

23out.write("本网站有如下书:
");

24Set>set=DB.getAll().entrySet();

25for(Map.Entryme:set){

26Bookbook=me.getValue();

27Stringurl=request.getContextPath()+"/servlet/BuyServlet?id="+book.getId();

28//response.encodeURL(java.lang.Stringurl)用于对表单action和超链接的url地址进行重写

29url=response.encodeURL(url);//将超链接的url地址进行重写

30out.println(book.getName()+"购买
");

31}

32}

33

34publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)

35throwsServletException,IOException{

36doGet(request,response);

37}

38}

39

40

41/

42@authorgacl

43模拟数据库

44/

45classDB{

46privatestaticMapmap=newLinkedHashMap();

47static{

48map.put("1",newBook("1","javaweb开发"));

49map.put("2",newBook("2","spring开发"));

50map.put("3",newBook("3","hibernate开发"));

51map.put("4",newBook("4","struts开发"));

52map.put("5",newBook("5","ajax开发"));

53}

54

55publicstaticMapgetAll(){

56returnmap;

57}

58}

59

60classBook{

61

62privateStringid;

63privateStringname;

64

65publicBook(){

66super();

67}

68publicBook(Stringid,Stringname){

69super();

70this.id=id;

71this.name=name;

72}

73publicStringgetId(){

74returnid;

75}

76publicvoidsetId(Stringid){

77this.id=id;

78}

79publicStringgetName(){

80returnname;

81}

82publicvoidsetName(Stringname){

83this.name=name;

84}

85}

复制代码

BuyServlet



复制代码

1packagexdp.gacl.session;

2

3importjava.io.IOException;

4importjava.util.ArrayList;

5importjava.util.List;

6importjavax.servlet.ServletException;

7importjavax.servlet.http.HttpServlet;

8importjavax.servlet.http.HttpServletRequest;

9importjavax.servlet.http.HttpServletResponse;

10importjavax.servlet.http.HttpSession;

11

12publicclassBuyServletextendsHttpServlet{

13

14publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)

15throwsServletException,IOException{

16Stringid=request.getParameter("id");

17Bookbook=DB.getAll().get(id);//得到用户想买的书

18HttpSessionsession=request.getSession();

19Listlist=(List)session.getAttribute("list");//得到用户用于保存所有书的容器

20if(list==null){

21list=newArrayList();

22session.setAttribute("list",list);

23}

24list.add(book);

25//response.encodeRedirectURL(java.lang.Stringurl)用于对sendRedirect方法后的url地址进行重写

26Stringurl=response.encodeRedirectURL(request.getContextPath()+"/servlet/ListCartServlet");

27System.out.println(url);

28response.sendRedirect(url);

29}

30

31publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)

32throwsServletException,IOException{

33doGet(request,response);

34}

35

36}

复制代码

ListCartServlet



复制代码

1packagexdp.gacl.session;

2

3importjava.io.IOException;

4importjava.io.PrintWriter;

5importjava.util.List;

6importjavax.servlet.ServletException;

7importjavax.servlet.http.HttpServlet;

8importjavax.servlet.http.HttpServletRequest;

9importjavax.servlet.http.HttpServletResponse;

10importjavax.servlet.http.HttpSession;

11

12publicclassListCartServletextendsHttpServlet{

13

14publicvoiddoGet(HttpServletRequestrequest,HttpServletResponseresponse)

15throwsServletException,IOException{

16response.setContentType("text/html;charset=UTF-8");

17PrintWriterout=response.getWriter();

18HttpSessionsession=request.getSession();

19Listlist=(List)session.getAttribute("list");

20if(list==null||list.size()==0){

21out.write("对不起,您还没有购买任何商品!!");

22return;

23}

24

25//显示用户买过的商品

26out.write("您买过如下商品:
");

27for(Bookbook:list){

28out.write(book.getName()+"
");

29}

30}

31

32publicvoiddoPost(HttpServletRequestrequest,HttpServletResponseresponse)

33throwsServletException,IOException{

34doGet(request,response);

35}

36}

复制代码

通过查看IndexServlet生成的html代码可以看到,每一个超链接后面都带上了session的Id,1本网站有如下书:
javaweb开发购买


2spring开发购买


3hibernate开发购买


4struts开发购买


5ajax开发购买


所以,当浏览器禁用了cookie后,就可以用URL重写这种解决方案解决Session数据共享问题。而且response.encodeRedirectURL(java.lang.Stringurl)和response.encodeURL(java.lang.Stringurl)是两个非常智能的方法,当检测到浏览器没有禁用cookie时,那么就不进行URL重写了。我们在没有禁用cookie的火狐浏览器下访问,

浏览器第一次访问时,服务器创建Session,然后将Session的Id以Cookie的形式发送回给浏览器,response.encodeURL(java.lang.Stringurl)方法也将URL进行了重写,当点击刷新按钮第二次访问,由于火狐浏览器没有禁用cookie,所以第二次访问时带上了cookie,此时服务器就可以知道当前的客户端浏览器并没有禁用cookie,那么就通知response.encodeURL(java.lang.Stringurl)方法不用将URL进行重写了。



五、session对象的创建和销毁时机



5.1、session对象的创建时机



在程序中第一次调用request.getSession()方法时就会创建一个新的Session,可以用isNew()方法来判断Session是不是新创建的



范例:创建session



复制代码

1//使用request对象的getSession()获取session,如果session不存在则创建一个

2HttpSessionsession=request.getSession();

3//获取session的Id

4StringsessionId=session.getId();

5//判断session是不是新创建的

6if(session.isNew()){

7response.getWriter().print("session创建成功,session的id是:"+sessionId);

8}else{

9response.getWriter().print("服务器已经存在session,session的id是:"+sessionId);

10}

复制代码

5.2、session对象的销毁时机



session对象默认30分钟没有使用,则服务器会自动销毁session,在web.xml文件中可以手工配置session的失效时间,例如:



复制代码

1

2
3xmlns="http://session.com/xml/ns/javaee"

4xmlns:xsi="http://2001/XMLSchema-instance"

5xsi:schemaLocation="http://www.wang027.com/xml/ns/javaee

6http://session.com/xml/ns/javaee/web-app_2_5.xsd">

7

8

9

10index.jsp

11


12

13

14

1515

16


17

18

复制代码

当需要在程序中手动设置Session失效时,可以手工调用session.invalidate方法,摧毁session。



1HttpSessionsession=request.getSession();

2//手工调用session.invalidate方法,摧毁session

3session.invalidate();

献花(0)
+1
(本文系thedust79首藏)