A-A+
使用ThreadLocal共享HttpSession
之前在使用.NET进行Web开发时,可以通过HttpContext.User在应用的任何层面获取当前登录的用户信息,而在使用Java进行Web开发时,最开始接触的就是SpringMVC,可是看到的都是形如下面的代码去获取Session中的用户信息。
- public ModelAndView getTest(HttpServletRequest request, HttpServletResponse response){
- String userId = request.getSession().getAttribute("user").toString();
- }
上面的代码没什么错误,只是看起来很别扭。最开始我以为没什么比较简单的办法来进行封装,直到前些日子开发权限管理系统的时候在这里卡壳了,逼着我去翻阅资料解决这个问题,于是找了几个开源的项目看了看源码,在搜索引擎上大海捞了个针,最后发现其实Java是有解决办法的,只不过需要自己封装一下,同样可以达到.NET下的那种效果。
首先,需要一个封装类。
- import javax.servlet.ServletContext;
- import javax.servlet.http.Cookie;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import javax.servlet.http.HttpSession;
- import java.util.HashMap;
- import java.util.Map;
- public class HttpContext {
- private HttpServletRequest request;
- private HttpServletResponse response;
- private final static ThreadLocal<HttpContext> contextContainer = new ThreadLocal<HttpContext>();
- /**
- * 初始化
- */
- public static HttpContext begin(HttpServletRequest req, HttpServletResponse res) {
- HttpContext context = new HttpContext();
- context.request = req;
- context.response = res;
- contextContainer.set(context);
- return context;
- }
- public static HttpContext get(){
- return contextContainer.get();
- }
- /**
- * 销毁
- */
- public void end() {
- this.request = null;
- this.response = null;
- contextContainer.remove();
- }
- public ServletContext getContext() {
- return this.request.getServletContext();
- }
- public HttpSession getSession() {
- return this.request.getSession(false);
- }
- public HttpServletRequest getRequest() {
- return this.request;
- }
- public HttpServletResponse getResponse() {
- return this.response;
- }
- public Map<String, Cookie> getCookies() {
- Map<String, Cookie> map = new HashMap<String, Cookie>();
- Cookie[] cookies = this.request.getCookies();
- if(cookies != null)
- for(Cookie ck : cookies) {
- map.put(ck.getName(), ck);
- }
- return map;
- }
- }
然后,需要一个Filter。
- import javax.servlet.*;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import java.io.IOException;
- /**
- * HttpContext全局过滤器
- */
- public class ContextFilter implements Filter{
- public void init(FilterConfig filterConfig) throws ServletException {
- }
- public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
- HttpServletRequest req = (HttpServletRequest)servletRequest;
- HttpServletResponse res = (HttpServletResponse)servletResponse;
- HttpContext.begin(req, res);
- filterChain.doFilter(servletRequest, servletResponse);
- }
- public void destroy() {
- HttpContext.get().end();
- }
- }
最后,就可以直接使用了,比如获取Session内的人员ID。
- /**
- * 获得当前登录人员的凭证信息
- */
- public static String getId(){
- HttpSession session = HttpContext.get().getSession();
- Object obj = null;
- if (null != session){
- obj = session.getAttribute("USERID");
- }
- if (null == obj) {
- return null;
- }
- return obj.toString();
- }
这个方法可以在任何位置调用,比如我在做权限管理系统时,就在自定义FileSqlManager时就获取了当前登录人员的ID,然后通过该人员的权限过滤出了SQL语句的条件,进而完成了SQL语句的构造,可以参见基于Nutz.Dao的数据权限管理的实现2。
相关的资料可以查看: