ThreadLocal get() 在未调用 set() 方法时给出意外结果
ThreadLocal get() gives unexpected result when set() method is not invoked
我有包含 ThreadLocal 的基础 class :
@Singleton
public class BaseView extends HttpServlet {
protected ThreadLocal<Locale> locale = new ThreadLocal<Locale>();
private Locale getLocale() {
return (Locale) ObjectUtils.defaultIfNull(locale.get(), Locale.ENGLISH);
}
...
}
并在 EmailValidatedView 中扩展:
@Singleton
public class EmailValidatedView extends BaseView {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String token = req.getParameter("token");
if (token != null) {
try {
User user = userService.validateEmail(token);
locale.set(user.parseLocale());
} catch (ServiceException e) {
e.printStackTrace();
}
}
sendResponse("validatedEmail.vm", resp.getWriter(), $());
}
}
当令牌无效时,我得到 ServiceException 并且未设置语言环境。在这种情况下,sendResponse() 方法应使用默认语言环境 - 英语。但是,如果我在浏览器中使用无效令牌刷新同一页面,我可能每次都会得到 different/non 相关语言。为什么会这样?
大多数 HTTP 服务器重用池中的线程。保持线程安全的配置是一件好事,ThreadLocal 可以提供帮助,但是您的逻辑结构使得您的语言环境不会在每次请求时都被重置。因此,过去请求中线程的旧语言环境会渗漏也就不足为奇了。
您需要确保每个读取它的请求都设置了区域设置,并且每个新请求都设置了默认区域设置(或者等效地清除 ThreadLocal 值)。
我有包含 ThreadLocal 的基础 class :
@Singleton
public class BaseView extends HttpServlet {
protected ThreadLocal<Locale> locale = new ThreadLocal<Locale>();
private Locale getLocale() {
return (Locale) ObjectUtils.defaultIfNull(locale.get(), Locale.ENGLISH);
}
...
}
并在 EmailValidatedView 中扩展:
@Singleton
public class EmailValidatedView extends BaseView {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String token = req.getParameter("token");
if (token != null) {
try {
User user = userService.validateEmail(token);
locale.set(user.parseLocale());
} catch (ServiceException e) {
e.printStackTrace();
}
}
sendResponse("validatedEmail.vm", resp.getWriter(), $());
}
}
当令牌无效时,我得到 ServiceException 并且未设置语言环境。在这种情况下,sendResponse() 方法应使用默认语言环境 - 英语。但是,如果我在浏览器中使用无效令牌刷新同一页面,我可能每次都会得到 different/non 相关语言。为什么会这样?
大多数 HTTP 服务器重用池中的线程。保持线程安全的配置是一件好事,ThreadLocal 可以提供帮助,但是您的逻辑结构使得您的语言环境不会在每次请求时都被重置。因此,过去请求中线程的旧语言环境会渗漏也就不足为奇了。
您需要确保每个读取它的请求都设置了区域设置,并且每个新请求都设置了默认区域设置(或者等效地清除 ThreadLocal 值)。