版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/cdnight/article/details/86702749
前言
自定义session插件,将它们统一存放到一个redis中可以有效避免分布式web应用的session不同步的问题。
下面就来尝试写一份session插件—注意,这是初稿来的,可以保证能跑得动,不过性能优化等等需要进一步自行实现的。切记。
添加对应的配置类以及工具类
在WebExt下面添加对应的类,如下图:
代码分别是:
SessionConf
package net.w2p.WebExt.config;
import com.xxl.conf.core.annotation.XxlConf;
/***
*
* 自定义session配置,全系统通用。
* ****/
public class SessionConf {
private static final String VarPrefix="session.";
public final static String sessionInitKey="___rsession__init";
/***session assets在request.setAttribute中的key。***/
public final static String httpReqAttrKey4SessAssets="rsession_assets";
/***
*
* 在redis中保存时候的key的前缀,key的规则是,prefix+sessionId
* ***/
@XxlConf(VarPrefix+"storePrefix")
public String storePrefix="session_";
/****
* 该参数是浏览器或者url中作为sessionId的参数的名字,默认为token,而类似的有jsessionid,phpsessionid
* 等等,可以随便改。
*
* ****/
@XxlConf(VarPrefix+"sessionCookieName")
public String sessionCookieName="ztoken";
/***
* 是否允许url传输sessionid
* ***/
@XxlConf(VarPrefix+"allowUrlWithSid")
public Boolean allowUrlWithSid=true;
public String getStorePrefix() {
return storePrefix;
}
public void setStorePrefix(String storePrefix) {
this.storePrefix = storePrefix;
}
public String getSessionCookieName() {
return sessionCookieName;
}
public void setSessionCookieName(String sessionCookieName) {
this.sessionCookieName = sessionCookieName;
}
public Boolean getAllowUrlWithSid() {
return allowUrlWithSid;
}
public void setAllowUrlWithSid(Boolean allowUrlWithSid) {
this.allowUrlWithSid = allowUrlWithSid;
}
}
SessionRedisCache
package net.w2p.WebExt.Session;
import net.w2p.WebExt.Plugins.RedisPlugin;
import redis.clients.jedis.Jedis;
import java.util.concurrent.ConcurrentHashMap;
public class SessionRedisCache {
public static final Integer MaxVisitPerSecond=10000;
public static final ConcurrentHashMap<String, Jedis> cache_redis=new ConcurrentHashMap<>(MaxVisitPerSecond);
}
SessionAssets
package net.w2p.WebExt.Session;
import java.io.Serializable;
/***
* session 杂项
* ***/
public class SessionAssets implements Serializable {
public String sessionId="";
public String redisClientId="";
//--这是redis里面直接存储的key。即 storagePrefix+sessionId
public String storageKey="";
public String getStorageKey() {
return storageKey;
}
public void setStorageKey(String storageKey) {
this.storageKey = storageKey;
}
/****
* 是否需要在response输出时候设定session cookie
* ***/
public Boolean needSetSessionCookie=false;
public String getSessionId() {
return sessionId;
}
public void setSessionId(String sessionId) {
this.sessionId = sessionId;
}
public String getRedisClientId() {
return redisClientId;
}
public void setRedisClientId(String redisClientId) {
this.redisClientId = redisClientId;
}
public Boolean getNeedSetSessionCookie() {
return needSetSessionCookie;
}
public void setNeedSetSessionCookie(Boolean needSetSessionCookie) {
this.needSetSessionCookie = needSetSessionCookie;
}
}
package net.w2p.WebExt.Session;
import net.w2p.WebExt.Plugins.RedisPlugin;
import redis.clients.jedis.Jedis;
import java.util.concurrent.ConcurrentHashMap;
public class SessionRedisCache {
public static final Integer MaxVisitPerSecond=10000;
public static final ConcurrentHashMap<String, Jedis> cache_redis=new ConcurrentHashMap<>(MaxVisitPerSecond);
}
RSession
package net.w2p.WebExt.Session;
import com.alibaba.fastjson.JSONObject;
import net.w2p.Shared.common.ValidateUtils;
import net.w2p.WebExt.config.SessionConf;
import redis.clients.jedis.Jedis;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
public class RSession {
private HttpServletRequest request;
private SessionAssets assets=null;
private Jedis redis=null;
protected RSession(HttpServletRequest request){
this.request=request;
if(!ValidateUtils.isEmpty(request.getAttribute(SessionConf.httpReqAttrKey4SessAssets))){
assets=(SessionAssets)request.getAttribute(SessionConf.httpReqAttrKey4SessAssets);
redis= SessionRedisCache.cache_redis.get(assets.redisClientId);
}
}
public String getToken(){
if(this.assets==null){
return null;
}
return this.assets.sessionId;
}
public static RSession getSession(HttpServletRequest request){
RSession session=new RSession(request);
return session;
}
public String getVal(String key){
if(assets==null){
return null;
}
String res=redis.hget(assets.storageKey, key);
return res;
}
public <T> T getVal(Class<T> classType,String key){
String res=getVal(key);
if(ValidateUtils.isEmpty(res)){
return null;
}
T object = JSONObject.parseObject(res,classType);
//Json.fromJson(classType, res);
return object;
}
public <T> List<T> getList(Class<T> classType,String key){
String res=getVal(key);
if(ValidateUtils.isEmpty(res)){
return null;
}
List<T> object = JSONObject.parseArray(res,classType);// Json.fromJsonAsList(classType, res);
return object;
}
// public <T> Map<String,T> getMap(Class<T> classType,String key){
// String res=getVal(key);
// if(ValidateUtils.isEmpty(res)){
// return null;
// }
// Map<String,T> object = JSONObject.ma Json.fromJsonAsMap(classType, res);
// return object;
// }
public void setVal(String key,Object value){
// Jedis redis= RedisUtil.getJedis();
if(assets==null){
return;
}
if(value==null){
return;
}
String res="";
if(value instanceof String){
res=(String)value;
}
else{
res=JSONObject.toJSONString(value);//.toJson(value);
}
redis.hset(assets.storageKey, key, res);
}
public boolean remove(String key){
// Jedis redis= RedisUtil.getJedis();
if(assets==null){
return false;
}
redis.hdel(assets.storageKey, key);
return true;
}
}
SessionInterceptor
package net.w2p.WebExt.Session;
import net.w2p.Shared.common.OpResult;
import net.w2p.Shared.common.RandomStringUtil;
import net.w2p.Shared.common.ValidateUtils;
import net.w2p.Shared.common.WebTools;
import net.w2p.WebExt.Plugins.CryptoPlugin;
import net.w2p.WebExt.Plugins.RedisPlugin;
import net.w2p.WebExt.config.SessionConf;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
import redis.clients.jedis.Jedis;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.HashMap;
import java.util.Random;
import java.util.UUID;
/**
* 注意:该文件用于对spring框架进行自定义session处理。
* 这是一个拦截器,请将其排列为最优先---在所有需要用到session之前的。
* -_- ps:这个版本的session拦截器是配合spring使用的,她依赖于redis插件,Crypto插件,还有需要有
* SessionConf对象,所以,配置时候记得传入到到拦截器的构造函数中。
*/
public class SessionInterceptor extends HandlerInterceptorAdapter {
public static final int SECONDS_30=30;
public static final int Minutes_ONE=60;
public static final int Minutes_TWO=120;
public static final int Minutes_THREE=180;
public static final int Minutes_FOUR=240;
public static final int Minutes_FIVE=300;
public static final int Minutes_30=60*30;
public static final int HOUR_1=60*60;
public static final int HOUR_5=60*60*5;
public static final int HOUR_12=60*60*12;
public static final int DAY_1=60*60*24;
public static final int DAY_2=60*60*48;
public static final int DAY_10=60*60*24*10;
public static final int DAY_30=60*60*24*30;
private RedisPlugin redisPlugin;
private SessionConf sessionConf;
private CryptoPlugin cryptoPlugin;
public SessionInterceptor(SessionConf sessionConf,RedisPlugin redisPlugin,CryptoPlugin cryptoPlugin){
this.redisPlugin=redisPlugin;
this.cryptoPlugin=cryptoPlugin;
this.sessionConf=sessionConf;
}
/**
* 得到一个字符串形式的格式化UUID
* @return
*/
public static String getStrUUID(){
Random random = new Random();
int end = random.nextInt(999);
//如果不足三位前面补0
String endStr =String.format("%03d", end);
return UUID.randomUUID().toString().replace("-", "")+endStr;
}
/**
* 生成加密以后的session id字符串。
* **/
private String getSessionId() throws Exception{
String random_chars= RandomStringUtil.getRandomCode(6, 6);
String key=getStrUUID()+"_"+(WebTools.getPhpTimeStamp(new Date().getTime()))+"_"+random_chars;
return this.cryptoPlugin.md5WithKey(key);
}
private String getRedisClientPrimaryKey() throws Exception{
String random_chars= RandomStringUtil.getRandomCode(6, 6);
String key="redis_client_"+getStrUUID()+(WebTools.getPhpTimeStamp(new Date().getTime()))+"_"+random_chars;
return this.cryptoPlugin.md5WithKey(key);
}
/****检查是否需要发送session id等等,主要是生成sessionAssets***/
private SessionAssets handleSessionRequest(HttpServletRequest request,HttpServletResponse response) throws Exception {
System.out.println("进入 session 初始化");
//--获取redis连接。
Jedis redisClient=redisPlugin.getJedis();
String redisClientPk=null;
redisClientPk= getRedisClientPrimaryKey();
SessionRedisCache.cache_redis.put(redisClientPk,redisClient);
SessionAssets assets=new SessionAssets();
assets.redisClientId=redisClientPk;
String clientSessionId=null;//--假如有session cookie或者url中带有sid的话,就放到这个变量里面去。
/***
*
* 检查request中是否有session cookie。
* ***/
Cookie sessionCookie=null;
if(request!=null){
Cookie[] cookies=request.getCookies();
if(cookies!=null){
for(Cookie item:cookies){
if(item.getName().equals(sessionConf.sessionCookieName)){
sessionCookie=item;
break;
}
}
}
//--如果request没有携带session cookie的话,那么判断是否允许在url上面传递sessionid
//--可以的话,就获取,不可以就不获取
if(sessionCookie==null){
//--好了,从request里面取一个token字段,有的话也默认是。
if(sessionConf.allowUrlWithSid){
}
else{
System.out.println("系统不允许从url上面传递sessionid,故此不分析。");
}
try{
HashMap<String,String> query_params=WebTools.getQueryParam(request.getQueryString());
if(query_params.containsKey(sessionConf.sessionCookieName)){
String tokenStr=query_params.get(sessionConf.sessionCookieName);
if(!ValidateUtils.isEmpty(tokenStr)){
clientSessionId =tokenStr;
}
}
}
catch (Exception ed){
ed.printStackTrace();
}
finally {
}
}
else{
clientSessionId=sessionCookie.getValue();
}
}
else{
throw new Exception("request对象为null!!!");
}
if(ValidateUtils.isEmpty(clientSessionId)){
assets.sessionId=getSessionId();
assets.needSetSessionCookie=true;
}
else if(redisClient.exists(sessionConf.storePrefix+clientSessionId)){
//--在redis中包含有这个sessionid,那么可以认为这次的session是合法的。
assets.needSetSessionCookie=false;
assets.sessionId=clientSessionId;
}
else{
//--clientsessionid非空,不过redis里面没有的,这是伪造的sessionid。重新发一个过去。
assets.needSetSessionCookie=true;
assets.sessionId=getSessionId();
}
//--assets放入request中。
request.setAttribute(SessionConf.httpReqAttrKey4SessAssets,assets);
assets.storageKey=sessionConf.storePrefix+assets.sessionId;
if(assets.needSetSessionCookie){
setSessionCookie(request,response,assets.sessionId);
}
else{
redisClient.expire(assets.storageKey,DAY_30);
}
return assets;
}
/***
* 需要时候,设置session cookie。
* @param request request对象
* @param response response 输出对象
* @param token 需要写入session cookie的sessionid。
* ***/
private OpResult setSessionCookie(HttpServletRequest request,HttpServletResponse response,String token) throws Exception{
OpResult opResult=new OpResult();
if(ValidateUtils.isEmpty(request.getAttribute(sessionConf.httpReqAttrKey4SessAssets))){
return opResult.setError("无法确认redis客户端连接!");
}
SessionAssets assets=(SessionAssets)request.getAttribute(sessionConf.httpReqAttrKey4SessAssets);
String redisClientPk=assets.redisClientId;
Jedis redis=SessionRedisCache.cache_redis.get(redisClientPk);
StringBuffer url = request.getRequestURL();
String tempContextUrl = url.delete(url.length() -
request.getRequestURI().length(), url.length()).append("/").toString();
if(tempContextUrl.indexOf("localhost")!=-1){
//--对于cookie来说,这可不是合法domain,换了他。
tempContextUrl=tempContextUrl.replace("localhost","127.0.0.1");
}
tempContextUrl="/";
String sessionKey = ValidateUtils.isEmpty(token)?getSessionId():token;
redis.hset(sessionConf.storePrefix+sessionKey, SessionConf.sessionInitKey, "1");
redis.expire(sessionKey, Minutes_THREE);//--新创建的session 默认时间是3分钟是因为,可能这个sid对方没接收的。。
String[] resCookieNames=new String[]{sessionConf.sessionCookieName};
for(String cookieName:resCookieNames){
Cookie sCookie=new Cookie(cookieName,sessionKey);
// sessionCookie.setDomain(tempContextUrl);
sCookie.setPath("/");
sCookie.setMaxAge(DAY_30); // 一天
response.addCookie(sCookie);
//--额外添加到response头部去
response.setHeader(sessionConf.sessionCookieName,sessionKey);
}
opResult.setSuccess("成功创建");
return opResult;
}
//--释放redis链接资源。
private void tryReleaseResource(HttpServletRequest request){
if(ValidateUtils.isEmpty(request.getAttribute(sessionConf.httpReqAttrKey4SessAssets))){
return;
}
SessionAssets assets=(SessionAssets)request.getAttribute(sessionConf.httpReqAttrKey4SessAssets);
String redisClientPk=assets.redisClientId;
Jedis redis=SessionRedisCache.cache_redis.get(redisClientPk);
if(redis!=null){
redisPlugin.returnResource(redis);
SessionRedisCache.cache_redis.remove(assets.redisClientId);
}
}
public boolean preHandle(HttpServletRequest request,
HttpServletResponse response, Object handler) throws Exception {
/***session begin ***/
System.out.println("=========【SessionInterceptor】执行 preHandle");
HttpServletRequest req=(HttpServletRequest)request;
HttpServletResponse resp=(HttpServletResponse)response;
System.out.println("开始处理session。");
//--检查session具体情况。
handleSessionRequest(request,response);
return super.preHandle(request, response, handler);
}
public void postHandle(HttpServletRequest request,
HttpServletResponse response, Object handler,
org.springframework.web.servlet.ModelAndView modelAndView)
throws Exception {
// 你自己的业务逻辑
//下面这句话不要动,就这样放着。你在处理你的业务逻辑之后,spring会将你的请求和响应继续往容器传或者往客户端进行传递
super.postHandle(request, response, handler, modelAndView);
}
/***注意,只有在当前拦截器【对于sessionInterceptor来说就是自己了】异常,才无法进入自身的afterCompletion方法,而其他错误即使报错,afterCompletion也是会执行的,不需要过分担心redis链接没有释放的问题。***/
public void afterCompletion(HttpServletRequest request,
HttpServletResponse response, Object handler, Exception ex)
throws Exception {
// 你自己的业务逻辑
System.out.println("=========【SessionInterceptor】执行 afterCompletion");
try{
//--三个方面保证可以释放redis资源,一个正常lastFilter释放,一个400,500释放,一个定时任务释放。一个last process释放---在nutz框架内,所以,应该可以了。
// System.out.println("=============执行到最后一个过滤器,释放资源。注意,并非所有请求都可以进行到这一步的,譬如,400,500就会到相应处理页面了,但是,起码一大部分正常执行的操作会释放redis资源的。");
System.out.println("释放redis链接。");
tryReleaseResource((HttpServletRequest)request);
}
catch (Exception ed){
ed.printStackTrace();
}
//下面这句话不要动,就这样放着。你在处理你的业务逻辑之后,spring会将你的请求和响应继续往容器传或者往客户端进行传递
super.afterCompletion(request, response, handler, ex);
}
}
初始化配置中心的数据
请执行
-- session 相关配置
create or replace function "initSessionConfig"(
in envName varchar
)
returns varchar
as $BODY$
declare _defaultValues varchar;
declare _envName varchar;
declare _appname varchar;
declare _prefix varchar;
declare strArrays varchar[];
declare arrItemLv1 varchar;
declare tempArrSubItem varchar;
declare valArrs varchar[];
declare item_attr varchar;
declare item_title varchar;
declare item_val varchar;
begin
if envName <> 'test' and envName<> 'ppe' and envName<> 'product' then
raise notice '环境变量异常,只能为test、ppe以及product其中一个。';
return '环境变量异常,只能为test、ppe以及product其中一个。';
end if;
_appname:='session';
_prefix:=concat(_appname,'.','');
_defaultValues:='storePrefix->在redis中保存时候的key的前缀,key的规则是,prefix+sessionId->session_$$' ||
'sessionCookieName->该参数是浏览器或者url中作为sessionId的参数的名字,默认为ztoken,而类似的有jsessionid,phpsessionid等等,可以随便改。->ztoken$$' ||
'allowUrlWithSid->是否允许url传输sessionid->true$$'
;
strArrays:=string_to_array(_defaultValues,'$$');
_envName:=envName;
-- fastdfs.connect_timeout_in_seconds = 5
-- fastdfs.network_timeout_in_seconds = 30
-- fastdfs.charset = UTF-8
-- fastdfs.http_anti_steal_token = false
-- fastdfs.http_secret_key = FastDFS1234567890
-- fastdfs.http_tracker_http_port = 80
-- #fastdfs.tracker_servers = tw-server:22122,10.0.11.202:22122,10.0.11.203:22122
-- fastdfs.tracker_servers = localhost:22122
-- fastdfs.visit_url = http://localhost/
-- env varchar(100) not null,
-- key varchar(200) not null,
-- appname varchar(100) not null,
-- title varchar(100) not null,
-- value varchar(2000) default NULL::character varying,
insert into xxl_conf_project (appname, title) values (_appname,'session全局配置') on conflict ("appname") do nothing;
<<loop4BigArray>>
foreach arrItemLv1 in array strArrays
loop
if char_length(arrItemLv1) < 1 then
raise notice '空字符串无须处理';
continue ;
end if;
valArrs:=string_to_array(arrItemLv1,'->');
item_attr:=valArrs[1];
item_title:=valArrs[2];
item_val:=valArrs[3];
raise notice '属性名称:%,描述:%,当前值:%',item_attr,item_title,item_val;
raise notice '开始添加记录';
insert into xxl_conf_node("env","key","appname","title","value")
values (_envName,concat(_prefix,item_attr),_appname,item_title,item_val)
on conflict ("env","key") do nothing ;
end loop loop4BigArray;
return envName||'环境下的'||_appName||'配置成功';
end;
$BODY$ language plpgsql volatile ;
-- 记住执行下面方法分别添加三个环境下的默认数据。
-- select "initSessionConfig"('test');
-- select "initSessionConfig"('ppe');
-- select "initSessionConfig"('product');
-- session 需要用到的redis单独做一份配置,是全局配置形式的。
create or replace function "initSessionRedisConfig"(
in envName varchar
)
returns varchar
as $BODY$
declare _defaultValues varchar;
declare _envName varchar;
declare _appname varchar;
declare _prefix varchar;
declare strArrays varchar[];
declare arrItemLv1 varchar;
declare tempArrSubItem varchar;
declare valArrs varchar[];
declare item_attr varchar;
declare item_title varchar;
declare item_val varchar;
begin
if envName <> 'test' and envName<> 'ppe' and envName<> 'product' then
raise notice '环境变量异常,只能为test、ppe以及product其中一个。';
return '环境变量异常,只能为test、ppe以及product其中一个。';
end if;
_appname:='session';
_prefix:=concat(_appname,'.redis.','');
_defaultValues:=
'auth->验证用的密码,假如没有不需要验证的话,请留空->$$' ||
'dbIndex->redis默认使用的db的序号【共有12个】->1$$' ||
'host->redis服务器所在ip地址或者hostname->localhost$$' ||
'max_active->redis最大激活连接数量->1000$$' ||
'max_idle->redis控制一个pool最多有多少个状态为idle(空闲的)的jedis实例,默认值也是8。->200$$' ||
'max_wait->等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException;->5000$$' ||
'needAuth->是否需要验证,输入 true 或者 false 两种布尔值->false$$' ||
'port->redis的服务端口,请填写数字->6379$$' ||
'test_on_borrow->在borrow一个jedis实例时,是否提前进行validate操作;如果为true,则得到的jedis实例均是可用的->true$$' ||
'timeout->超时时间->10000$$'
;
strArrays:=string_to_array(_defaultValues,'$$');
_envName:=envName;
-- fastdfs.connect_timeout_in_seconds = 5
-- fastdfs.network_timeout_in_seconds = 30
-- fastdfs.charset = UTF-8
-- fastdfs.http_anti_steal_token = false
-- fastdfs.http_secret_key = FastDFS1234567890
-- fastdfs.http_tracker_http_port = 80
-- #fastdfs.tracker_servers = tw-server:22122,10.0.11.202:22122,10.0.11.203:22122
-- fastdfs.tracker_servers = localhost:22122
-- fastdfs.visit_url = http://localhost/
-- env varchar(100) not null,
-- key varchar(200) not null,
-- appname varchar(100) not null,
-- title varchar(100) not null,
-- value varchar(2000) default NULL::character varying,
insert into xxl_conf_project (appname, title) values (_appname,'session全局配置') on conflict ("appname") do nothing;
<<loop4BigArray>>
foreach arrItemLv1 in array strArrays
loop
if char_length(arrItemLv1) < 1 then
raise notice '空字符串无须处理';
continue ;
end if;
valArrs:=string_to_array(arrItemLv1,'->');
item_attr:=valArrs[1];
item_title:=valArrs[2];
item_val:=valArrs[3];
raise notice '属性名称:%,描述:%,当前值:%',item_attr,item_title,item_val;
raise notice '开始添加记录';
insert into xxl_conf_node("env","key","appname","title","value")
values (_envName,concat(_prefix,item_attr),_appname,item_title,item_val)
on conflict ("env","key") do nothing ;
end loop loop4BigArray;
return envName||'环境下的'||_appName||'配置成功';
end;
$BODY$ language plpgsql volatile ;
-- 记住执行下面方法分别添加三个环境下的默认数据。
-- select "initSessionRedisConfig"('test');
-- select "initSessionRedisConfig"('ppe');
-- select "initSessionRedisConfig"('product');
用工具远程登录配置中心的数据库,直接执行即可:
select "initSessionConfig"('test');
select "initSessionConfig"('ppe');
select "initSessionConfig"('product');
select "initSessionRedisConfig"('test');
select "initSessionRedisConfig"('ppe');
select "initSessionRedisConfig"('product');
使用java代码整合到spring中进行设置
在MasterWebApp中整合。
BeanConfiguration下面添加:
package net.w2p.local.plugins.BeanConfiguration;
import com.xxl.conf.core.XxlConfClient;
import net.w2p.WebExt.Plugins.CryptoPlugin;
import net.w2p.WebExt.Plugins.RedisPlugin;
import net.w2p.WebExt.Session.SessionInterceptor;
import net.w2p.WebExt.config.RedisConf;
import net.w2p.WebExt.config.SessionConf;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.HandlerInterceptor;
/***
*
* 这是自定义的session机制。session将放到redis中。
* 注意,出于各个子模块网站都需要用同一个session,所以所有网站session存放的redis应该要是同一个才行。
* 这意味这这里还需要多一个redisConf,请在整合了的redisConf上面添加@Primary 注解,这个redisconf是session专用不是默认的。
* ***/
@Configuration
public class SessionConfiguration {
@Bean(name="sessionRedisConf")
public RedisConf sessionRedisConf(){
RedisConf redisConf=new RedisConf();
final String VarPrefix="session.redis.";
redisConf.needAuth= XxlConfClient.getBoolean(VarPrefix+"needAuth");
redisConf.auth=XxlConfClient.get(VarPrefix+"auth");
redisConf.host=XxlConfClient.get(VarPrefix+"host");
redisConf.port=XxlConfClient.getInt(VarPrefix+"port");
redisConf.dbIndex=XxlConfClient.getInt(VarPrefix+"dbIndex");
redisConf.max_active=XxlConfClient.getInt(VarPrefix+"max_active");
redisConf.max_idle=XxlConfClient.getInt(VarPrefix+"max_idle");
redisConf.max_wait=XxlConfClient.getInt(VarPrefix+"max_wait");
redisConf.timeout=XxlConfClient.getInt(VarPrefix+"timeout");
redisConf.test_on_borrow=XxlConfClient.getBoolean(VarPrefix+"test_on_borrow");
return redisConf;
}
@Bean(name="sessionConf")
public SessionConf sessionConf(){
SessionConf conf=new SessionConf();
return conf;
}
@Bean(name="sessRedis")
@Autowired
public RedisPlugin sessRedis(@Qualifier("sessionRedisConf") RedisConf conf){
RedisPlugin plugin=new RedisPlugin(conf);
return plugin;
}
/****初始化 session 拦截器****/
// @Bean("sessionInterceptor")
// @Autowired
// public HandlerInterceptor sessionInterceptor(@Qualifier("cryptoPlugin") CryptoPlugin cryptoPlugin
// , @Qualifier("sessRedis") RedisPlugin sessRedis
// , @Qualifier("sessionConf") SessionConf sessionConf
// ){
// SessionInterceptor interceptor=new SessionInterceptor(sessionConf,sessRedis,cryptoPlugin);
//
// return interceptor;
// }
}
在spring-mvc.xml中注册拦截器
代码如下:
<!--拦截器 配置 begin -->
<mvc:interceptors>
<!--设定session拦截器-->
<mvc:interceptor>
<!-- 进行拦截:/**表示拦截所有controller -->
<mvc:mapping path="/**" />
<bean class="net.w2p.WebExt.Session.SessionInterceptor">
<!--注意,session interceptor构造函数需要几个参数,别忘记了-->
<constructor-arg name="sessionConf"
ref="sessionConf"></constructor-arg>
<constructor-arg name="cryptoPlugin"
ref="cryptoPlugin"></constructor-arg>
<constructor-arg name="redisPlugin"
ref="sessRedis"></constructor-arg>
</bean>
</mvc:interceptor>
<!--设定session拦截器 end-->
</mvc:interceptors>
<!--拦截器 配置 end -->
进行测试
启动网站,访问/hello/index.do
然后查看控制台输出:
可以看到系统生成的session已经放到cookie里面去了。
一切正常。
结语
自己编写session插件本身是相对来说有难度的,无论是从session机制考虑,还是从整个流程来看都有一定难度,需要慢慢调试整个代码,整个流程。