天天看点

JavaEE 要懂的小事:三、图解Session(会话)一、Session由来二、Session机制三、详细介绍Seesion机制过程四、补充五、总结

http的无状态,也就是说,每次请求都是独立的线程。举个例子吧:购物中,你选择了a商品,加入购物车,这就是a线程。然后在选择b商品就是b线程。可是每次线程独立(对容器而言,a、b成了不同的用户),线程a不知道有b,b也不知道a。如何一起付款呢?

简答来说:怎么保存同个用户多个请求会话状态呢?自然https保证连接是安全的,可以使它与一个会话关联。

问题就在于如何跟踪同一个用户,选择自然很多:

1、ejb(有状态会话bean保存会话状态) 环境苛刻需要带ejb的j2ee服务器,而不是tomcat这种web容器。 2、数据库(这貌似万能的。针对数据) 3、就是我们要讲的httpseesion,保存跨一个特定用户多个请求的会话状态。 4、上面说的https,条件太苛刻了。
JavaEE 要懂的小事:三、图解Session(会话)一、Session由来二、Session机制三、详细介绍Seesion机制过程四、补充五、总结

机制,什么用词有点高大上。其实就是把它内在的一点东西说出来。主要两个w:what?how?

what is session?

session代表着服务器和客户端一次会话的过程。直到session失效(服务端关闭),或者客户端关闭时结束。

how does session works?

session 是存储在服务端的,并针对每个客户端(客户),通过sessionid来区别不同用户的。session是以cookie技术或url重写实现。默认以cookie技术实现,服务端会给这次会话创造一个jsessionid的cookie值。

补充:

其实还有一种技术:表单隐藏字段。它也可以实现session机制。这里只是作为补充,服务器响应前,会修改form表单,添加一个sessionid类似的隐藏域,以便传回服务端的时候可以标示出此会话。 这技术,也可以使用在web安全上,可以有效地控制crsf跨站请求伪造。
JavaEE 要懂的小事:三、图解Session(会话)一、Session由来二、Session机制三、详细介绍Seesion机制过程四、补充五、总结

图中这是session第一次请求的详细图。以cookie技术实现,我也写了个httpsessionbycookieservlett.java 的servlet小demo,模拟下seesion的一生。代码如下:

<a href="http://www.bysocket.com/?p=384#">?</a>

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

<code>package</code> <code>org.servlet.sessionmngmt;</code>

<code>import</code> <code>java.io.ioexception;</code>

<code>import</code> <code>java.io.printwriter;</code>

<code>import</code> <code>javax.servlet.servletexception;</code>

<code>import</code> <code>javax.servlet.annotation.webservlet;</code>

<code>import</code> <code>javax.servlet.http.httpservlet;</code>

<code>import</code> <code>javax.servlet.http.httpservletrequest;</code>

<code>import</code> <code>javax.servlet.http.httpservletresponse;</code>

<code>import</code> <code>javax.servlet.http.httpsession;</code>

<code>/*</code>

<code> </code><code>* copyright [2015] [jeff lee]</code>

<code> </code><code>*</code>

<code> </code><code>* licensed under the apache license, version 2.0 (the "license");</code>

<code> </code><code>* you may not use this file except in compliance with the license.</code>

<code> </code><code>* you may obtain a copy of the license at</code>

<code> </code><code>* unless required by applicable law or agreed to in writing, software</code>

<code> </code><code>* distributed under the license is distributed on an "as is" basis,</code>

<code> </code><code>* without warranties or conditions of any kind, either express or implied.</code>

<code> </code><code>* see the license for the specific language governing permissions and</code>

<code> </code><code>* limitations under the license.</code>

<code> </code><code>*/</code>

<code>/**</code>

<code> </code><code>* @author jeff lee</code>

<code> </code><code>* @since 2015-7-12 10:58:28</code>

<code> </code><code>*  httpsession的默认cookie实现案例</code>

<code>@webservlet</code><code>(urlpatterns =</code><code>"/sessionbycookie"</code><code>)</code>

<code>public</code> <code>class</code> <code>httpsessionbycookieservlett</code><code>extends</code> <code>httpservlet {</code>

<code>    </code><code>private</code> <code>static</code> <code>final</code> <code>long</code> <code>serialversionuid = 1l;</code>

<code>    </code><code>@override</code>

<code>    </code><code>protected</code> <code>void</code> <code>doget(httpservletrequest req, httpservletresponse resp)</code>

<code>            </code><code>throws</code> <code>servletexception, ioexception {</code>

<code>        </code> 

<code>        </code><code>// 获取session</code>

<code>        </code><code>// 如果是第一次请求的话,会创建一个httpseesion,等同于 req.getsession(true);</code>

<code>        </code><code>// 如果已存在session,则会获取session。</code>

<code>        </code><code>httpsession session = req.getsession();</code>

<code>        </code><code>if</code> <code>(session.isnew()) {</code>

<code>            </code><code>// 设置session属性值</code>

<code>            </code><code>session.setattribute(</code><code>"name"</code><code>,</code><code>"jeff"</code><code>);</code>

<code>        </code><code>}</code>

<code>        </code><code>// 获取sessionid</code>

<code>        </code><code>string sessionid = session.getid();</code>

<code>        </code><code>printwriter out = resp.getwriter();</code>

<code>        </code><code>// 如果httpseesion是新建的话</code>

<code>            </code><code>out.println(</code><code>"hello,httpsession! &lt;br&gt;the first response - seesionid="</code>

<code>                    </code><code>+ sessionid +</code><code>" &lt;br&gt;"</code><code>);</code>

<code>        </code><code>}</code><code>else</code> <code>{</code>

<code>            </code><code>out.println(</code><code>"hello,httpsession! &lt;br&gt;the second response - seesionid="</code>

<code>            </code><code>// 从session获取属性值</code>

<code>            </code><code>out.println(</code><code>"the second-response - name: "</code>

<code>                    </code><code>+ session.getattribute(</code><code>"name"</code><code>));</code>

<code>    </code><code>}</code>

<code>    </code> 

<code>}</code>

隆重打个小广告:

① 客户端向服务端发送第一次请求

此时,客户端想让服务端把自己的名字设置到会话中。

② 服务端的容器产生该用户唯一sessionid的session对象,并设置值

可以从代码中看出通过从请求中req.getsession(),新生成了一个session对象。并设置了setattribute(“name”, “jeff”),key为string,value是对象皆可。

这时候,我们不用再把session通过cookie技术处理,容器帮我们处理了。

③ 容器响应 set-cookie:jsessionid= …

我们可以f12,查看此次响应。

JavaEE 要懂的小事:三、图解Session(会话)一、Session由来二、Session机制三、详细介绍Seesion机制过程四、补充五、总结

从图中可得到,每个cookie的set,都有一个对应set-cookie的头。httponly可是此cookie只读模式。只不过session唯一标识是:jsessionid

④ 浏览器解析cookie,保存至浏览器文件。

JavaEE 要懂的小事:三、图解Session(会话)一、Session由来二、Session机制三、详细介绍Seesion机制过程四、补充五、总结

第二次请求会发什么变化呢?

JavaEE 要懂的小事:三、图解Session(会话)一、Session由来二、Session机制三、详细介绍Seesion机制过程四、补充五、总结

下面,泥瓦匠重新访问了这个地址:

① 再次请求

JavaEE 要懂的小事:三、图解Session(会话)一、Session由来二、Session机制三、详细介绍Seesion机制过程四、补充五、总结

此时,请求会有cookie值:jsessionid=… 该值传给服务端

② 容器获取sessionid

,关联httpsession

③ 此时响应无setcookie

如图:

JavaEE 要懂的小事:三、图解Session(会话)一、Session由来二、Session机制三、详细介绍Seesion机制过程四、补充五、总结

但是这次请求,我们响应出上一次请求set的值。jeff 就打印出来了!

关于服务端获取session,也就是从请求中获取session对象,容器会帮你根据cookie找到唯一的session对象。

泥瓦匠记忆小抄:seesion机制,记住两次请求图即可。

点到为止哈~ 以后详细写。此图来自网络

JavaEE 要懂的小事:三、图解Session(会话)一、Session由来二、Session机制三、详细介绍Seesion机制过程四、补充五、总结

上图bad guy,就是攻击者。跨站请求伪造,伪造用户请求来对服务器数据或者是用户等造成威胁。web安全也就是从这些基础中慢慢提升。

1、大概地描述了session的工作机制,和一些安全相关。记住seesion是什么,怎么用,在服务端客户端之间怎么传输即可。