我有一个使用 Jersey (1.17) 和 Guice (3.0) 的 Java 项目。 SessionScoped bean 在本地开发中工作,但在 GAE 上部署时不起作用。问题是他们不保持 session 状态。
session 在 web.xml 中启用:<sessions-enabled>true</sessions-enabled>
我的 session 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; }
}
它绑定(bind)到 ServletModule 中的 Session 范围 bind(SessionService.class).in(ServletScopes.SESSION);
我使用它的 Controller 是:
@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 做些什么。这是为什么?
最佳答案
我找到了一种方法来获得所需的类似 SessionScoped 的功能。不要使用 @SessionScoped
因为它显然不适用于 GAE,而是使用 Provider<HttpSession>
.
所以你的代码会像
public class SessionService {
@Inject Provider<HttpSession> httpSessionProvider;
public void saveSecurityInfo(Object securityInfo) {
httpSessionProvider.get().setAttribute('sec_info', securityInfo);
}
public Object loadSecurityInfo() {
return httpSessionProvider.get().getAttribute('sec_info');
}
}
在 Controller 中,您可以将其作为 @Inject SessionService sessionService;
插入
我已经在 GAE 上测试了这种方法并且它有效(在浏览器 session 中保留信息)。
关于java - SessionScoped 不工作 GAE+Jersey+Guice,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24181622/