共计 3634 个字符,预计需要花费 10 分钟才能阅读完成。
HttpSession 的内容都放在一个单独的 Map 中,模拟远程分布式 Session。
1. 使用 HttpServletRequestWrapper 创建自定义 Request
2. 使用动态代理包装自定义 Request 返回的 HttpSession 对象
3. 创建过滤器,使用自定义 Request 替换原有的 Request 对象。
4. 在 Servlet 中得到的 HttpSession 对象,写入和读取内容都假设通过远程 Session 服务器。
创建自定义的 Request,返回动态代理的 HttpSession
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import javax.servlet.http.HttpSession;
public class RemoteSessionRequest extends HttpServletRequestWrapper {
public RemoteSessionRequest(HttpServletRequest request) {
super(request);
}
@Override
public HttpSession getSession() {
return RemoteSessionHandler.getInstance(super.getSession());
}
}
class RemoteSessionHandler implements InvocationHandler {
// 模拟远程 Session 服务器,Key 表示 SessionId,Value 表示该 Session 的内容
private static Map<String, Map<String, Object>> map = new ConcurrentHashMap<String, Map<String, Object>>();
private HttpSession session = null;
private RemoteSessionHandler(HttpSession httpSession) {
this.session = httpSession;
};
public static HttpSession getInstance(HttpSession httpSession) {
InvocationHandler handler = new RemoteSessionHandler(httpSession);
return (HttpSession) Proxy.newProxyInstance(httpSession.getClass().getClassLoader(), httpSession.getClass().getInterfaces(), handler);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if (“setAttribute”.equals(method.getName())) {
String id = session.getId();
Map<String, Object> m = map.get(id);
if (m == null) {
m = new HashMap<String, Object>();
map.put(id, m);
}
m.put((String) args[0], args[1]);
System.out.println(“[ 存入]key:” + args[0] + “,value:” + args[1]);
return null;
} else if (“getAttribute”.equals(method.getName())) {
String id = session.getId();
Map<String, Object> m = map.get(id);
if (m == null) {
return null;
}
Object result = m.get(args[0]);
System.out.println(“[ 取出]key:” + args[0] + “,value:” + result);
return result;
}
return method.invoke(session, args);
}
}
使用过滤器替换原有的 Request
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.annotation.WebFilter;
import javax.servlet.http.HttpServletRequest;
@WebFilter(“/*”)
public class SessionFilter implements Filter {
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
chain.doFilter(new RemoteSessionRequest((HttpServletRequest) request), response);
}
@Override
public void destroy() {
// TODO Auto-generated method stub
}
@Override
public void init(FilterConfig arg0) throws ServletException {
// TODO Auto-generated method stub
}
}
在 Servlet 中按照原有方式使用 HttpSession。
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
HttpSession session = request.getSession();
session.setAttribute(“name”, “Hello”);
session.getAttribute(“name”);
session.getAttribute(“other”);
}
结果可以看到,他已经模拟从远程服务器存取数据
[存入]key:name,value:Hello
[取出]key:name,value:Hello
[取出]key:other,value:null
HBase 0.94.21+ZooKeeper-3.4.6 分布式安装 http://www.linuxidc.com/Linux/2014-09/106534.htm
CentOS 6.0 下 Zabbix 分布式监控系统的初步搭建 http://www.linuxidc.com/Linux/2014-08/105003.htm
Hadoop 分布式部署 http://www.linuxidc.com/Linux/2014-07/104795.htm