SessionScoped不工作GAE + Jersey + Guice

时间:2014-06-12 10:01:18

标签: java google-app-engine jersey guice session-scope

我有一个Java项目,我使用Jersey(1.17)和Guice(3.0)。 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 bind(SessionService.class).in(ServletScopes.SESSION);

中的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做一些事情。那是为什么?

1 个答案:

答案 0 :(得分:1)

我找到了一种如何获得所需的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');
    }
}

在控制器中,您可以将其插入@Inject SessionService sessionService;

我已经在GAE上测试了这种方法,它可以工作(在浏览器会话中保存信息)。