您的位置:首页 > 其它

如何在Service层获取用户session中保存的用户信息的方法(Filter+ThreadLocal)

2016-07-06 14:33 811 查看
/**
 * 
 * Description: 用ThreadLocal提供一个存储线程内变量的地方. <p/>
 * 客户端代码可以用静态方法存储和获取线程内变量,不需要依赖于HttpSession.
 * web层的Controller可通过此处向business层传入user_id之类的变量
 * 
 */
@SuppressWarnings("unchecked")
public class UserSession {
    /** * 保存变量的ThreadLocal,保持在同一线程中同步数据. */
    private static final ThreadLocal SESSION_MAP = new ThreadLocal();

    /** * 工具类的protected构造方法. */
    protected UserSession() {
    }

    /**
     * 获得线程中保存的属性.
     * 
     * @param attribute
     *            属性名称
     * @return 属性值
     */
    public static Object get(String attribute) {
        Map map = (Map) SESSION_MAP.get();
        System.out.println(map.toString());
        System.out.println(map.containsKey("usersession"));

        return map.get(attribute);
    }

    /**
     * 获得线程中保存的属性,使用指定类型进行转型.
     * 
     * @param attribute
     *            属性名称
     * @param clazz
     *            类型
     * @param <T>
     *            自动转型
     * @return 属性值
     */
    public static <T> T get(String attribute, Class<T> clazz) {
        return (T) get(attribute);
    }

    /**
     * 设置制定属性名的值.
     * 
     * @param attribute
     *            属性名称
     * @param value
     *            属性值
     */
    public static void set(String attribute, Object value) {
        Map map = (Map) SESSION_MAP.get();

        if (map == null) {
            map = new HashMap();
            SESSION_MAP.set(map);
        }

        map.put(attribute, value);
    }

}

我在用户登录的时候 执行:

UserSession.set("User",User);

然后在我需要的service层中执行:

UserSession.get("User");

//UserSession.get("User",User.class);

此时会出现一个bug:这样第一次取到session中的User对象,后面的请求都取不到了。

解决方法:ThreadLocal 是当前请求(前台对后台的每个请求都会被认为是一个独立的线程)的对象。每一次线程请求的时候,都需要从session中把session对象取出来。放到ThreadLocal中去(最好的方式是通过filter拦截器实现)。 这样才能从service中取得到。acegi就是这么处理的

拦截器代码:

public class SessionFilterUtil implements Filter {

    public void destroy() {

    }

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

        HttpServletRequest session_request = (HttpServletRequest) request;

        HttpServletResponse session_response = (HttpServletResponse) response;

        HttpSession session = session_request.getSession();

        User user = (User) session.getAttribute("user");

        if (user != null) {

            UserSession.set("userSession", session);

            chain.doFilter(request, response);

        } else {

            String uri = session_request.getRequestURI();         // 获取uri信息

            String ctx = session_request.getContextPath();         // 获取上下文,如/项目名

            if(uri.indexOf("!") != -1){

                String method = uri.substring(uri.indexOf("!") + 1, uri.indexOf(".action"));

                if(method.equals("bistore_login")){

                    chain.doFilter(request, response);

                }

            }

            session_response.getWriter().print("<script>location.href='" + ctx + "/adf/login!bistore_login.action'</script>");

        }

    }

    public void init(FilterConfig filterConfig) throws ServletException {

    }

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: