我正在我的Java Web应用程序中研究和试验ThreadLocal变量。我使用ThreadLocal变量在请求之前存储用户名(从会话中收集),然后在请求之后将其删除。我通过在Servlet Filter中调用一个静态实用程序方法来实现这一点。我之所以不简单地从会话中检索用户名,是因为我继承了一个系统,该系统具有长时间运行的进程,这些进程有时需要比会话超时所允许的更长的时间来运行。我的想法是在处理请求之前获取用户名,并将其存储在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>
任何想法都非常感谢:)