有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java会话无法处理GAE+Jersey+Guice

我有一个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; }
}

并且它绑定到ServletModulebind(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(); }
}

使用本地dev服务器,它可以正常工作。在GAE(1.9.5)上部署时,它会第一次设置区域设置,然后永远保持不变,即使我一次又一次地调用setLocale。为什么它不起作用

奇怪的是,我找到了一个模糊的方法使它工作,但我不知道为什么它使它工作。要使其运行,必须在设置区域设置之前触摸HttpSession。像request.getSession(true).setAttribute("whatever", "bar")。好像服务器需要被调用,SessionService希望对会话执行某些操作。为什么呢


共 (1) 个答案

  1. # 1 楼答案

    我找到了一种方法,可以获得所需的会话处理功能。不要使用@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上测试了这种方法,它可以工作(将信息保存在浏览器会话中)