I am researching and experimenting with a ThreadLocal variable in my Java Web Application. I am using the ThreadLocal variable to store a username (collected from the session) before a request, and then removing it after the request. I have done this by calling a static utility method in a ServletFilter. The reason I do not simply retrieve the username from the session is because I have inherited a system with long-running processes that sometimes take longer to run than the session timeout would allow. My idea is to grab the username before the request is processed and store it in a ThreadLocal variable, thus giving me access to the username throughout the duration of the request even if it takes longer than 1开发者_如何学运维5 minutes.
My question is:
Are there any security/performance concerns with this design, and if so, what would be a better solution? Even if there aren't any security and/or performance issues, better ideas are welcome. Snippets from my solution are shown below:
Here is my utility class that would be called in my filter and anywhere that I would need the username.
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();
}
}
Here is my servlet filter used to set the username before the request (and clear it via the finally block after the request).
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();
}
}
}
Here's my web.xml configuration:
<!--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>
Any ideas are much appreciated :)
This is actually a fairly common approach for attaching security information to the thread of execution (or any other execution related information).
It is used in Java EE servers internally and by 3rd party code/utils like Spring as well.
It will work just fine.
精彩评论