我有包含ThreadLocal的基类:
@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()方法应该使用默认语言环境 - 英语。但是,如果我使用无效令牌在浏览器中刷新同一页面,我可能每次都会得到不同/不相关的语言。为什么会这样?
答案 0 :(得分:1)
大多数HTTP服务器都会重用池中的线程。保持线程安全配置是一件好事,ThreadLocal可以提供帮助,但是您的逻辑结构使得您的语言环境不会在每次请求时重置。因此,毫不奇怪,来自过去请求的线程的旧语言环境将会流失。
您需要确保每个读取它的请求都设置了您的语言环境,并且为每个新请求设置了默认语言环境(或者等效地清除了ThreadLocal值)。