Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
x-hansong committed Apr 29, 2016
1 parent 1d3aa48 commit f18b7c2
Show file tree
Hide file tree
Showing 17 changed files with 996 additions and 0 deletions.
57 changes: 57 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio


## Directory-based project format:
.idea/
.gradle/
gradle/
# if you remove the above rule, at least ignore the following:

# User-specific stuff:
# .idea/workspace.xml
# .idea/tasks.xml
# .idea/dictionaries
# .idea/shelf

# Sensitive or high-churn files:
# .idea/dataSources.ids
# .idea/dataSources.xml
# .idea/sqlDataSources.xml
# .idea/dynamic.xml
# .idea/uiDesigner.xml

# Gradle:
# .idea/gradle.xml
# .idea/libraries

# Mongo Explorer plugin:
# .idea/mongoSettings.xml

## File-based project format:
*.ipr
*.iws
*.iml
*.log

## Plugin-specific files:

# IntelliJ
out/
gen/
build/

# mpeltonen/sbt-idea plugin
.idea_modules/

# JIRA plugin
atlassian-ide-plugin.xml

# Crashlytics plugin (for Android Studio and IntelliJ)
com_crashlytics_export_strings.xml
crashlytics.properties
crashlytics-build.properties
fabric.properties


# gradle files
gradlew*
22 changes: 22 additions & 0 deletions Core/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
group 'hansong'
version '1.0-SNAPSHOT'

apply plugin: 'java'

sourceCompatibility = 1.5

repositories {
mavenCentral()
}

dependencies {
compile (
'javax:javaee-api:7.0',
'redis.clients:jedis:2.8.0',
"ch.qos.logback:logback-classic:1.0.13",
'com.fasterxml.jackson.core:jackson-core:2.7.3',
'com.fasterxml.jackson.core:jackson-databind:2.7.3',
'commons-lang:commons-lang:2.3'
)
testCompile group: 'junit', name: 'junit', version: '4.11'
}
19 changes: 19 additions & 0 deletions Core/redis.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
{
"cluster":"false",

"connectionConfig": {
"maxTotal": "10",
"maxIdle": "10",
"maxWait": "10000",
"timeout": "10000"
},

"redisServers":[
{
"ip":"112.74.215.22",
"port":"63679",
"password":"a12shg"
}
]

}
207 changes: 207 additions & 0 deletions Core/src/main/java/com/hansong/session/RedisHttpSession.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,207 @@
package com.hansong.session;

import com.hansong.session.redis.RedisConnection;

import javax.servlet.ServletContext;
import javax.servlet.http.HttpSession;
import javax.servlet.http.HttpSessionContext;
import java.io.Serializable;
import java.util.*;

/**
* Created by xhans on 2016/4/27.
*/
public class RedisHttpSession implements HttpSession{

public static final int DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS = 1800;

private static final String SESSION_PREFIX = "session:";
private static final String SESSION_ATTR = "sessionAttr:";
private static final String CREATION_TIME = "creationTime";
private static final String LAST_ACCESSED_TIME = "lastAccessedTime";
private static final String MAX_INACTIVE_INTERVAL = "maxInactiveInterval";

private String key;
private String id;
private long creationTime;
private long lastAccessedTime;
private int maxInactiveInterval;

private ServletContext servletContext;

private RedisConnection redisConnection;

private RedisHttpSession(){}


private RedisHttpSession(ServletContext servletContext, RedisConnection redisConnection) {
this.servletContext = servletContext;
this.redisConnection = redisConnection;
id = UUID.randomUUID().toString();
key = SESSION_PREFIX + id;
creationTime = System.currentTimeMillis();
lastAccessedTime = creationTime;
maxInactiveInterval = DEFAULT_MAX_INACTIVE_INTERVAL_SECONDS;
//save to redis
saveSession();
}

public static RedisHttpSession createNew(ServletContext servletContext, RedisConnection redisConnection){
return new RedisHttpSession(servletContext, redisConnection);
}

public static RedisHttpSession createWithExistSession(String token, ServletContext servletContext, RedisConnection redisConnection){
RedisHttpSession redisHttpSession= new RedisHttpSession();
redisHttpSession.setId(token);
redisHttpSession.setKey(SESSION_PREFIX + token);
redisHttpSession.setServletContext(servletContext);
redisHttpSession.setRedisConnection(redisConnection);

return redisHttpSession;
}

public void setId(String id) {
this.id = id;
}


public void setServletContext(ServletContext servletContext) {
this.servletContext = servletContext;
}

@Override
public long getCreationTime() {
return (long) redisConnection.hget(key, CREATION_TIME);
}

@Override
public String getId() {
return id;
}

@Override
public long getLastAccessedTime() {
return (long) redisConnection.hget(key, LAST_ACCESSED_TIME);
}

@Override
public ServletContext getServletContext() {
return servletContext;
}

@Override
public void setMaxInactiveInterval(int interval) {
redisConnection.hset(key, MAX_INACTIVE_INTERVAL, interval);
}

@Override
public int getMaxInactiveInterval() {
return (int) redisConnection.hget(key, MAX_INACTIVE_INTERVAL);
}

@Override
public HttpSessionContext getSessionContext() {
return null;
}

@Override
public Object getAttribute(String name) {
return redisConnection.hget(key, SESSION_ATTR + name);
}

@Override
public Object getValue(String name) {
return getAttribute(name);
}

@Override
public Enumeration<String> getAttributeNames() {
return Collections.enumeration(getAttributeKeys());
}

private Set<String> getAttributeKeys(){
Set<String> keys = redisConnection.hkeys(key);
Set<String> attrNames = new HashSet<>();
for (String key : keys){
if (key.startsWith(SESSION_ATTR)){
attrNames.add(key.substring(SESSION_ATTR.length()));
}
}
return attrNames;
}


@Override
public String[] getValueNames() {
return getAttributeKeys().toArray(new String[0]);
}

@Override
public void setAttribute(String name, Object value) {
redisConnection.hset(key, SESSION_ATTR + name, (Serializable) value);
}

@Override
public void putValue(String name, Object value) {
setAttribute(name, value);
}

@Override
public void removeAttribute(String name) {
redisConnection.hdel(key, name);
}

@Override
public void removeValue(String name) {
removeAttribute(name);
}

@Override
public void invalidate() {
redisConnection.del(key);
}

@Override
public boolean isNew() {
return false;
}

private void saveSession(){
redisConnection.hset(key, LAST_ACCESSED_TIME, lastAccessedTime);
redisConnection.hset(key, CREATION_TIME, creationTime);
redisConnection.hset(key, MAX_INACTIVE_INTERVAL, maxInactiveInterval);
refresh();
}

/**
* 更新过期时间
*/
public void refresh(){
redisConnection.expire(key, maxInactiveInterval);
}

public RedisConnection getRedisConnection() {
return redisConnection;
}

public void setRedisConnection(RedisConnection redisConnection) {
this.redisConnection = redisConnection;
}

public void setLastAccessedTime(long lastAccessedTime) {
redisConnection.hset(key, LAST_ACCESSED_TIME, lastAccessedTime);
}

public String getKey() {
return key;
}

public void setKey(String key) {
this.key = key;
}

public boolean isInvalidated() {
return redisConnection.exists(key);
}

}
25 changes: 25 additions & 0 deletions Core/src/main/java/com/hansong/session/RedisHttpSessionFilter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
package com.hansong.session;

import javax.servlet.*;
import java.io.IOException;

/**
* Created by xhans on 2016/4/27.
*/
public class RedisHttpSessionFilter implements Filter {

@Override
public void init(FilterConfig filterConfig) throws ServletException {

}

@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

}

@Override
public void destroy() {

}
}
44 changes: 44 additions & 0 deletions Core/src/main/java/com/hansong/session/RedisHttpSessionProxy.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
package com.hansong.session;

import com.hansong.session.redis.RedisConnection;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

/**
* Created by xhans on 2016/4/29.
*/
public class RedisHttpSessionProxy implements InvocationHandler {
private Object originalObj;

private RedisHttpSessionRepository repository = RedisHttpSessionRepository.getInstance();

public Object bind(Object originalObj) {
this.originalObj = originalObj;
return Proxy.newProxyInstance(originalObj.getClass().getClassLoader(), originalObj.getClass().getInterfaces(), this);
}

@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
RedisHttpSession session = (RedisHttpSession) originalObj;
//check redis connection
RedisConnection connection = session.getRedisConnection();
if (!connection.isConnected()){
connection.close();
session.setRedisConnection(repository.getRedisConnection());
}
//For every methods of interface, check it valid or not
if (!session.isInvalidated()){
throw new IllegalStateException("The HttpSession has already be invalidated.");
} else {
Object result = method.invoke(originalObj, args);
//if not invalidate method, refresh expireTime and lastAccessedTime;
if (!method.getName().equals("invalidate")) {
session.refresh();
session.setLastAccessedTime(System.currentTimeMillis());
}
return result;
}
}
}
Loading

0 comments on commit f18b7c2

Please sign in to comment.