public class MyFilter implements Filter {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) {
User user = tryGetAuthenticatedUser(request, response);
try (UserContext context = new UserContext(user)) {
chain.doFilter(request, response);
}
}
}
再來看我們的UserContext類:
public class UserContext implements AutoCloseable {
static final ThreadLocal<User> current = new ThreadLocal<User>();
public UserContext(User user) {
current.set(user);
}
public static User getCurrentUser() {
return current.get();
}
public void close() {
current.remove();
}
}
我們的過濾器攔截所有的請求,當我們登錄后,其他的接口會頻繁的使用到登錄后的用戶信息進行操作,我們不能每次都寫重復的代碼根據cookie中的信息取出相對應的UserInfo,所以就在Filter中進行統一處理,直接在接口中使用UserContext進行獲取即可,這里我們使用ThreadLocal進行UserInfo的存儲,SpringMVC默認情況下的Conteroller是單例的,也就是說我們的Controller在接收到用戶請求時,可能是不同的線程去操作controller的方法進行響應,所以應避免在Controller中聲明變量去共享使用,很容易造成多線程問題,此處使用ThreadLocal避免用戶信息錯亂的問題。