Webx框架:會話管理

在Servlet中,Session和Cookie是分開的。Session一般保存在內存中,當然也可以保存在數據庫等其他地方。如果保存在內存中,對於服務集羣來說就需要解決Session共享的問題。如果保存在數據庫,就存在單點故障、性能差等問題。

webx提供了會話框架,將session這樣複雜的問題統一進行解決。在webx框架中,主張將cookie合併到session中,再通過規則,路由到cookie或者session中。cookie保存在客戶端,session保存在服務端,它們的區別這裏就不贅述了。

webx中有一個SessionStore的概念。它相當於Session的保存容器。容器可以配置不同的編碼、加密方式等。與servlet配置類似,session的配置有storesstore-mappings。下面是一個簡單的例子(僅用於調試):

<session>
  <stores>
    <session-stores:simple-memory-store id="simple" />
  </stores>
  <store-mappings>
    <match name="*" store="simple" />
  </store-mappings>
</session>

SessionID。在Servlet中,默認是通過名爲JSESSIONID的Cookie保存SessionID。在webx中可以換用不同的Cookie名稱,而且SessionID的生成方法也可以改變。下面是改變SessionID字段的例子。

<session>
  <id cookieEnabled="true" urlEncodeEnabled="false">
    <cookie name="JSESSIONID" domain="" maxAge="0" path="/" httpOnly="true" secure="false" />
    <url-encode name="JSESSIONID" />
    <session-idgens:uuid-generator />
  </id>
</session>

Cookie屬性有下面幾個,都可以通過屬性進行設置。namedomainmaxAgepathhttpOnlysecure

與其他框架不同的是,如果Http請求中的SessionID不認識,之前沒有出現過,那麼會將HTTP請求中的SessionID作爲該客戶端的SessionID,而不是創建一個新的。這樣設計的好處是,有可能SessionID與其他應用共享,其他應用生成的SessionID是不能覆蓋的。

會話RequestContext的屬性有以下幾個。

屬性 作用
maxInactiveInterval Session的失效時間
keepInTouch 默認爲false。如果爲true,表示和servlet中的session模式一樣,每次讀取session的時候更新session,如果爲false,只有在session內容發生改變時才更新session時間。
forceExpirationPeriod 無視失效時間,即使這個session一直被訪問,超過這個事件,session還是會失效
modelKey 用於保存session狀態的對象名稱,一般不需要修改。默認爲SESSION_MODEL
會話儲存

SessionStore。下面是SessionStore的一個例子。

<stores>
  <session-stores:store id="store1" />
  <session-stores:store id="store2" />
  <session-stores:store id="store3" />
</stores>
<store-mappings>
  <match name="*" store="store1" />
  <match name="loginName" store="store2" />
  <matchRegex pattern="key.*" store="store3" />
</store-mappings>

match標籤採用了正則匹配,如果有多個規則符合正則表達式,那麼有下面的優先級:

  • 精確匹配最優先
  • 較長的regex優先
  • 默認規則爲*

默認規則只能有一個。

SessionModel。它是一個存放在Session中的字段,用於記錄Session中各個字段的生命週期數據,比如創建時間,最後更新時間等。它可以看成一個普通的session字段,因此可以配置匹配規則,放到指定的session容器中。

SessionModel可以轉換成字符串,默認是轉換成json,並作爲普通的字段保存到session中。

<session-model-encoders>
  <model-encoders:default-session-model-encoder />
  <model-encoders:model-encoder class="..." />
  <model-encoders:model-encoder class="..." />
</session-model-encoders>

Session攔截器。框架提供了兩個自帶的攔截器:lifecycle-loggerattribute-whitelist,它們的用法在下面這個例子中已經非常清楚了。當然也可以定義自己的攔截器,有兩種攔截器可以選擇:

  • SessionLifecycleListener:監聽Session的生成、銷燬、訪問事件。
  • SessionAttributeInterceptor:監聽Session的讀寫事件。 框架會根據基類自動配置不同的攔截器。
    <request-contexts:interceptors
    xmlns="http://www.alibaba.com/schema/services/request-contexts/session/interceptors">
    <lifecycle-logger />
    <attribute-whitelist>
      <attribute name="_csrf_token" />
      <attribute name="_lang" />
      <attribute name="loginUser" type="com.alibaba...MyUser" />
      <attribute name="shoppingCart" type="com.alibaba....ShoppingCart" />
    </attribute-whitelist>
    <interceptor class="..." />
    </request-contexts:interceptors>

CookieStore。有些安全性要求不高的session字段不必保存在服務端,而是保存在瀏覽器端。這樣對服務器的壓力也會小一些。

Cookie中只能存放字符串,而session中可以存放java對象,因此對接cookie和session需要將Java對象轉換成字符串。這種轉換交給encoder進行。配置方法如下:

<session-stores:cookie-store>
  ...
  <session-stores:encoders>
    <session-encoders:encoder class="..." />
    <session-encoders:encoder class="..." />
    <session-encoders:encoder class="..." />
  </session-stores:encoders>
</session-stores:cookie-store>

可以指定多個encoder,寫入session時,使用第一個encoder進行編碼,讀取session時,依次使用不同的解碼器進行解碼,直到正確解碼爲止。

框架自帶了幾個編碼器,默認使用hessian進行編碼。

<session-stores:encoders>
  <session-encoders:serialization-encoder />
</session-stores:encoders>

編碼後加密。

<session-encoders:serialization-encoder>
  <session-serializers:hessian-serializer />
  <session-encrypters:aes-encrypter key="0123456789abcdef" />
</session-encoders:serialization-encoder>

使用java原生序列化算法,這種算法的移植性最好。

<session-encoders:serialization-encoder>
  <session-serializers:java-serializer />
</session-encoders:serialization-encoder>

還有用於調試的內存SessionStore

<session-stores:simple-memory-store id="simple" />

每種SessionStore還可以設置加密、URLEncode、枚舉映射、自定義映射等。

有兩種CookieStore:單值和多值。

多值CookieStore,下面這個例子將session保存在tmp這個cookie中。由於cookie中的字段名稱是可以重複的,因此有幾個session就有幾個tmp的cookie。

<session-stores:cookie-store id="temporaryClientStore">
  <session-stores:cookie name="tmp" />
</session-stores:cookie-store>

單值CookieStore。下面是最簡單的例子:

<stores:single-valued-cookie-store id="loginNameCookie">
  <stores:cookie name="login" />
</stores:single-valued-cookie-store>
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章