我正在研究和试验我的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>
非常感谢任何想法:)
答案 0 :(得分:7)
这实际上是将安全信息附加到执行线程(或任何其他执行相关信息)的相当常见的方法。
它在内部使用Java EE服务器,也可以在Spring等第三方代码/ utils中使用。
它会正常工作。