12

我正在我的 Java Web 应用程序中研究和试验 ThreadLocal 变量。我正在使用 ThreadLocal 变量在请求之前存储用户名(从会话中收集),然后在请求之后将其删除。我通过调用 ServletFilter 中的静态实用程序方法来完成此操作。我不简单地从会话中检索用户名的原因是因为我继承了一个具有长时间运行进程的系统,有时运行时间比会话超时允许的时间长。我的想法是在处理请求之前获取用户名并将其存储在 ThreadLocal 变量中,这样即使需要超过 15 分钟,我也可以在整个请求期间访问用户名。

我的问题是:

这种设计是否存在任何安全/性能问题,如果有,什么是更好的解决方案?即使没有任何安全和/或性能问题,也欢迎更好的想法。我的解决方案中的片段如下所示:

这是我的实用程序类,它将在我的过滤器中以及我需要用户名的任何地方调用。

public abstract class UserUtil {
private static final ThreadLocal<String> threadUser = new ThreadLocal<String>();

public static String getUserId(){
    return threadUser.get();
}

public static void setUserId(String userId){
    threadUser.set(userId);
}

public static void removeUserId(){
    threadUser.remove();
}
}

这是我的 servlet 过滤器,用于在请求之前设置用户名(并在请求之后通过 finally 块清除它)。

public class UserFilter implements Filter {
public void init(FilterConfig filterConfig) throws ServletException {
}

public void destroy() {
}

public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
    try {
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        UserBean userBean = (UserBean) ((HttpServletRequest) servletRequest).getSession().getAttribute("userBean");
        UserUtil.setUserId(userBean.getUserId());

        filterChain.doFilter(servletRequest, servletResponse);
    } finally{
        UserUtil.removeUserId();
    }
}

}

这是我的 web.xml 配置:

<!--web.xml-->
<web-app>

...
...
...

<filter>
    <filter-name>UserFilter</filter-name>
    <filter-class>filter.UserFilter</filter-class>
</filter>
<filter-mapping>
    <filter-name>UserFilter</filter-name>
    <url-pattern>*.jsf</url-pattern>
</filter-mapping>

任何想法都非常感谢:)

4

1 回答 1

7

这实际上是将安全信息附加到执行线程(或任何其他与执行相关的信息)的相当常见的方法。

它在内部用于 Java EE 服务器,也被 Spring 等 3rd 方代码/实用程序使用。

它会工作得很好。

于 2011-06-02T16:43:20.260 回答