2

我正在开发一个 Web 应用程序,并且遇到了会话存储问题。

应用程序部署到集群中,我们放置一个 apache http 服务器来处理负载平衡。因此,每个请求可能由集群中的不同节点处理。我们开始使用 Redis(主/从)作为共享会话存储。

我的问题是如何将它插入 Spring mvc,这样我们就可以使用 redis 而不需要更改我们的应用程序代码。

我在互联网上找到了一个使用 Filter 和 HttpServletRequestWrapper 的解决方案:

public void doFilter(ServletRequest servletRequest,
        ServletResponse servletResponse, FilterChain filterChain)
        throws IOException, ServletException {
    //get sessionId from cookie or generate one if not found        
    filterChain.doFilter(new CustomHttpServletRequestWrapper(sid, request),
            servletResponse);
}

public class CustomHttpServletRequestWrapper extends HttpServletRequestWrapper {

    String sid = "";

    public HttpServletRequestWrapper(String sid, HttpServletRequest arg0) {
        super(arg0);
        this.sid = sid;
    }

    public HttpSession getSession(boolean create) {
        return new HttpSessionSidWrapper(this.sid, super.getSession(create));
    }

    public HttpSession getSession() {
        return new HttpSessionSidWrapper(this.sid, super.getSession());
    }
}

我想知道我是否可以在 spring mvc 中找到等价物?

我想到的第一个是HandlerInterceptor。但不像filter的api,HanlderIntercepor不处理链,所以没有办法将自定义请求传递给下一个拦截器。

任何想法都值得赞赏,在此先感谢。

更新:

我发现了关于这个主题的两个策略:

第一个是扩展您的 Web 容器(例如 Tomcat),并且已经有一些成熟的开源项目专注于它。

第二个是使用过滤器+包装器。该策略与 Web 容器无关。

我个人更喜欢第一个,因为它对开发人员是透明的。假设我们在测试/生产环境中使用 Weblogic,我们使用嵌入式码头进行开发,因为它更快并且需要更少的资源。在这种情况下,开发人员不必为开发设置会话存储。但是另一方面,如果我们采用第二种策略,每个开发人员都需要设置自己的会话存储。另一种解决方案是为开发环境提供共享会话存储或一些配置来切换会话存储策略(内置用于开发,共享用于测试/生产)。我认为通过spring执行依赖(配置)注入比通过原始servlet过滤器更容易,因此提出了这个问题。

顺便说一句,有谁知道 Weblogic 的第一个策略的开箱即用实现?

4

1 回答 1

1

我不知道 WebLogic 会话存储配置选项,但我可以评论基于过滤器的策略

您可以实施过滤器以了解其环境。您可以为开发添加配置,这将显示“不包装请求”并仅在生产(或测试)环境中启用包装。

您可以将过滤器实现为 Spring 应用程序上下文感知(检查WebApplicationContextUtils),甚至由 Spring 的应用程序上下文管理(通过DelegatingFilterProxy)。然后您将能够提取配置值或使用 Spring 配置文件手动设置过滤器。

于 2013-08-13T11:14:43.013 回答