我有一个使用 Jersey (1.17) 和 Guice (3.0) 的 Java 项目。SessionScoped bean 在本地开发中工作,但在 GAE 上部署时不起作用。问题是他们不保持会话状态。
会话在 web.xml 中启用:<sessions-enabled>true</sessions-enabled>
我的会话 bean (SessionService) 是:
@SessionScoped
public class SessionService implements Serializable {
@Inject transient Logger log;
private Locale locale = Locale.US;
public synchronized Locale getLocale() { return locale; }
public synchronized void setLocale(Locale locale) { this.locale = locale; }
}
它绑定到 ServletModule 中的 Session 范围bind(SessionService.class).in(ServletScopes.SESSION);
我使用它的控制器是:
@Path("/settings")
public class SettingsController {
@Inject SessionService sessionService;
@GET
@Path("/setLocale")
public Object setLocale(@QueryParam("languageTag") String languageTag) {
sessionService.setLocale(Locale.forLanguageTag(languageTag));
return "OK";
}
@GET
@Path("/getLocale")
public Object getLocale() { return sessionService.getLocale().getLanguage(); }
}
使用本地开发服务器可以正常工作。当部署在 GAE (1.9.5) 上时,它会第一次设置语言环境,然后即使我一次又一次地调用 setLocale,它也会永远保持不变。为什么它不起作用?
奇怪的是,我找到了一种使它起作用的晦涩方法,但我不知道为什么它使它起作用。要让它运行,有必要在设置语言环境之前触摸 HttpSession。喜欢request.getSession(true).setAttribute("whatever", "bar")
。好像需要召回服务器,SessionService 想要对 Session 做一些事情。这是为什么?