Spring-session+mongodb實現session共享
pom.xml配置
首先需要引入依賴包,直接在pom.xml中新增以下程式碼即可。
<!-- spring-session整合mongodb -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-mongo</artifactId>
<version>1.3.3.RELEASE</version>
</dependency>
這裡使用spring 4.x進行了專案的構建,這裡說明一下,本專案使用spring 4.x進行構建,5.x的配置方式改變,請繞行。根據mavean的官方描述,該引用包含spring-session以及spring-data-mongo,一次性引入
web.xml配置
第一步使用spring-session攔截session,再web.xml中配置攔截器,特別注意,這個攔截器一般來說應該是優先順序最高的,一定放到開頭,攔截配置如下
<!-- spring-session 注意我的位置,一定要非常靠前-->
<filter>
<filter-name>springSessionRepositoryFilter</filter-name>
<filter-class>org.springframework.web.filter.DelegatingFilterProxy</ filter-class>
</filter>
<filter-mapping>
<filter-name>springSessionRepositoryFilter</filter-name>
<url-pattern>/*</url-pattern>
</filter-mapping>
<!-- spring-session 結束-->
- 還是特別注意 ,一定要配置的很靠前,尤其系統內有使用者登入session校驗的,一定要在其後;
applicationContext.xml 核心配置檔案
首先在檔案頭我們增加mongodb的引用 頭部增加
xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xsi:schemaLocation中增加
http://www.springframework.org/schema/data/mongo
http://www.springframework.org/schema/data/mongo/spring-mongo.xsd
完整程式碼–我這裡引用了其他的,無視就好
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx" xmlns:mongo="http://www.springframework.org/schema/data/mongo"
xsi:schemaLocation="
http://www.springframework.org/schema/data/mongo
http://www.springframework.org/schema/data/mongo/spring-mongo.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-4.0.xsd
http://www.springframework.org/schema/tx
http://www.springframework.org/schema/tx/spring-tx-4.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-4.0.xsd">
增加mongodb的配置 注意一下這裡Host port等各種引數應該在外部配置檔案中,直接介紹圖方便直接寫在了配置檔案中
<!-- mongodb資料來源 -->
<mongo:mongo id="mongo" host="你的mongo的ip地址" port="你的mongo的埠">
<mongo:options connections-per-host="8" threads-allowed-to-block-for-connection-multiplier="4"
connect-timeout="1000" max-wait-time="1500" auto-connect-retry="true" socket-keep-alive="true" socket-timeout="1500"
slave-ok="true" write-number="1" write-timeout="0" write-fsync="true" />
</mongo:mongo>
<!-- mongo的工廠,通過它來取得mongo例項,testmongo為mongodb的資料庫名,沒有的話會自動建立 -->
<mongo:db-factory id="mongoDbFactory" dbname="testmongo" mongo-ref="mongo" />
<!-- mongodb的主要操作物件,所有對mongodb的增刪改查的操作都是通過它完成 -->
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
</bean>
增加mongodb對session的託管
<!-- 將session放入mongo -->
<bean id="mongoHttpSessionConfiguration"
class="org.springframework.session.data.mongo.config.annotation.web.http.MongoHttpSessionConfiguration">
<property name="maxInactiveIntervalInSeconds" value="1800" />
</bean>
在系統中使用session
以上已經配置完畢,我們啟動專案以後登入,會在剛才配置的mongo中自動建立一個名為sesssions的表,使用該語法檢視
db.sessions.find();
session正常已經正常存入了mongo,存入後,接下來涉及系統使用。我們都知道,再獲取session內物件的時候,我們使用session.getAttribute("")方法,如果此時session中僅是存的簡單的key-value格式,那麼到此為止,全部工作已經完成,但是如果session中存放了比較複雜的物件,存了key-object這種,在我們直接通過session.get獲取到內容以後,你會發現他是一個dbobject型別,結構為{aaa=123,bbb=456,ccc=789},這個內容無法直接強制轉換為我們想要的java物件。接下來就要藉助gson先將dbobject轉為jsonstr,再將jsonstr轉為obj
為了方便以後我們對session儲存複雜物件的時候進行操作,我們封裝一個工具類,用於獲取session物件
package com.easternie.newframe.util;
import java.text.DateFormat;
import java.util.Date;
import javax.servlet.http.HttpSession;
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
/**
* SessionUtil 用於處理是否使用mongodb作為session的快取
* @author ZhangQiang
* 注意=如果使用mongo進行seesion共享需要進行以下操作。
* 1、再pom.xml引入spring-session-data-mongo
* 2、applicationcontext中引入mongo的jdbc 並將mongo注入session
* 3、web.xml中增加spring-session的攔截-注意往前放,作為第一道攔截
*/
public class SessionUtils {
//設定是否開啟Mongo儲存session 如果為true 從mongo中處理,false直接返回session的內容本身
static Boolean DOMONGOTRACE = true;
public static <T> T getMongoSession(HttpSession session,Class<?> t) {
return getMongoSession(session,t,null);
}
/**
*
* @param session - httpsession
* @param t - xxx.class
* @param className - 注意全字母大寫,session的key理論上裝載以後就要全部大寫
* @return
*/
@SuppressWarnings("unchecked")
public static <T> T getMongoSession(HttpSession session,Class<?> t,String className) {
className = className == null? t.getSimpleName().toUpperCase() : className;
if(DOMONGOTRACE) {
Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, new DateDeserializer()).setDateFormat(DateFormat.LONG).create();
return (T) gson.fromJson(gson.toJson(session.getAttribute(className)), t);
}else {
return (T) session.getAttribute(className);
}
}
}
在需要獲取session中的物件的時候我們使用
User user = SessionUtils.getMongoSession(session, User.class);
這樣就可以輕易獲取到我們存入到session中的物件,注意一下封裝了兩個方法,無className的會自動根據t找名字,另外養成習慣我們插入session中的資料,全部大寫。這樣方便使用t直接找到。如果t的類名和存入session的key值不一致的時候,使用第二個方法。
細心的可能發現,在使用gson處理資料的時候,因為mongodb本身日期型別是和javascript的日期型別保持一致的,所以當我們直接存入java的date型別的時候,資料庫中對直接轉換為long型別的時間戳。那麼在gson進行轉換的時候,發現Longl型別的時間戳轉換為date的時候,就會報錯。 再gson轉換之前,我們先解決一下Long轉date的問題 新建DateDeserializer重寫deserialize方法,程式碼如下
package com.easternie.newframe.util;
import java.lang.reflect.Type;
import java.util.Date;
import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonParseException;
/** gson轉換的時候對於Long時間戳型別進行特殊處理
* @author ZhangQiang
* @date 2018年10月30日15:02:46
*/
public class DateDeserializer implements JsonDeserializer<Date> {
@Override
public Date deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
return new java.util.Date(json.getAsJsonPrimitive().getAsLong());
}
}
這樣在sessionutils中進行轉換的時候使用該方法進行處理,就不會異常了
Gson gson = new GsonBuilder().registerTypeAdapter(Date.class, new DateDeserializer()).setDateFormat(DateFormat.LONG).create();
該方法同樣適用於對於前臺js傳過來的某些個別的時間戳型別的日期資料。