【问题标题】:HttpServletRequest object change and Session drops after redirect重定向后 HttpServletRequest 对象更改和会话丢弃
【发布时间】:2017-01-01 14:21:13
【问题描述】:

我一直致力于在我的电子商务应用程序中实现Punchout。我的实现工作如下。

直到昨天一切正常,然后当重定向到店面发生时,会话开始丢弃

我的观察:

在重定向发生之前HttpServletRequest 对象是RequestFacade,但是在我重定向之后,它变成了ApplicationHttpRequest。我可以找到包裹在ApplicationHttpRequest 中的RequestFacade,但我找不到放入会话中的对象。下面是我用来将对象放入会话的函数。

/**
 * Creates an object of {@link PunchoutSessionDTO} and puts it in
 * the session, making it a punchout session.
 * 
 * @param punchoutTransaction
 *          The {@link PunchoutTransaction} object passed from the 
 *          {@link PunchoutStoreEntryController}.
 * @param session
 *          The {@link HttpSession}.
 */
public void createPunchoutSession(PunchoutTransaction punchoutTransaction, HttpSession session) {

    // Create a PunchoutSessionDTO object.
    PunchoutSessionDTO state = new PunchoutSessionDTO();

    // Initialize it with the variables from the PunchoutTransaction
    // object passed to it.
    state.setBrowserFormPost(punchoutTransaction.getCallbackURL());
    state.setBuyerCookie(punchoutTransaction.getBuyerCookie());
    state.setFromId(punchoutTransaction.getFromId());
    state.setToId(punchoutTransaction.getToId());
    state.setPoTransId(punchoutTransaction.getTransactionId());
    state.setOciPunchout(punchoutTransaction.getTransactionType() == PunchoutTransaction.TYPE_OCI);

    // And put it in the session, so that the session could be
    // identified as a punchout session.
    session.setAttribute("PunchoutState", state);

    // Set the max inactive interval of the session to the value
    // provided in the store property. If such store property is
    // not found, a default of 5 minutes is used.
    /*String vid = punchoutTransaction.getVendorId();
    Integer timeout = PunchoutStorePropertyFactory.getTimeoutPeriod(vid);
    session.setMaxInactiveInterval( (timeout == null ? 5 : timeout) * 60); */

    logger.info("Punchout Session Created for " + punchoutTransaction.getBuyerCookie());
}

在我决定应该为会话设置超时值之前,一切正常。在此之后,问题开始出现。起初,我以为我通过传递 setMaxInactiveInterval() 的错误值来搞砸了,所以我评论了它。令我惊讶的是,会话还是被放弃了。

请注意:

  • 我们在Windows 8.1 上使用Apache Tomcat
Server version: Apache Tomcat/7.0.54
Server built:   May 19 2014 10:26:15
Server number:  7.0.54.0
OS Name:        Windows 8
OS Version:     6.2
Architecture:   amd64
JVM Version:    1.7.0_51-b13
JVM Vendor:     Oracle Corporation
  • 我们使用的是 Spring 2.5。是的!而且我们无法迁移,因为这个应用程序非常庞大(超过 10,000 个源文件)。

  • URL 模式 *.po*.html 映射到同一个 servlet,因此重定向发生在同一个 servlet 内。

谷歌搜索:

  1. 为什么 HttpServletRequest 对象会发生变化。

  2. HttpServletRequest 更改为 ApplicationHttpRequest

  3. HttpServletRequest 到 ApplicationHttpRequest

  4. Spring ServletRequest 对象变化

  5. 重定向后HttpServletRequest发生变化

自过去 3 天以来,这个愚蠢的错误让我们很生气。任何帮助,将不胜感激!请指出我犯的任何愚蠢的错误,并且一些与会话处理/管理相关的好技巧是最受欢迎的。如果您认为我没有提供足够的信息,请同时指出。谢谢:)

【问题讨论】:

    标签: spring spring-mvc tomcat servlets


    【解决方案1】:

    是的,我正在回答我自己的问题。我想详细介绍一下,以便未来的人可以找到他们的答案。

    原来我是一个正在重定向到绝对路径的白痴。

    重定向是关键。

    无论您要重定向到的 servlet 是否驻留在同一个应用程序服务器上,是在同一个应用程序中,还是它甚至共享同一个 servlet。 任何重定向到绝对路径的请求都有自己的上下文!因此,为它们创建的请求对象是全新的,并且具有各自的会话。 只有在同一 porthostwebapp 上发送重定向时,才会维护会话。 如果在同一个应用程序中进行重定向,使用相对路径最好使用相对路径

    https://localhost/servlet1.html 重定向到http://localhost/servlet2.html 是非常不同的,即使 URL 映射到同一个 servlet(请注意区别)。

    https://localhost/servlet1.html 重定向到https://192.168.x.x/servlet2.htmlhttps://127.0.0.1/servlet2.html 会产生相同的结果。

    这里的最佳做法是重定向到相对于您的应用程序的路径。这将以最有效的方式共享会话对象。 使用response.sendRedirect("servlet2.html"); 是最好的选择(在我看来)。

    了解 Cookies

    会话由JSESSIONID cookie 标识。如果浏览器转发此 cookie,则会话将转发到其他 servlet 或控制器(或其他)。 HTTPHTTPs 是不同的协议,因此使用不同的 cookie。同样,localhost 和 IP 地址是浏览器的不同主机,因此使用不同的 cookie。如果protocolhostwebapp context 保持不变,则JSESSIONID cookie 被转发,但是这与在重定向中使用相对路径具有相同的含义。重定向到相对地址可以被认为是在相同主机、协议和应用程序上下文上重定向的安全方式。 浏览器决定是否转发您的JSESSIONID cookie

    【讨论】:

    • 嗯...我不知道这个答案是否有用。 ://
    • 您不了解 cookie 的工作原理,而这正是会话的关键。 https 到 http 是一个不同的 cookie。根据浏览器,IP 的 localhost 是不同的主机。您不需要使用相对路径。您需要使用相同的协议和主机。浏览器决定是否转发您的 JSESSIONID cookie。
    • @stdunbar 感谢您的参与。使用相对路径将重定向保持在相同的协议和主机上是不是正确的?
    • 是的,从这个角度来看,您是正确的——您的解决方案可以正常工作,我应该做得更好。但这不是必需 - 它只是让您更容易处理协议和主机更改。
    • 你的观点帮助我发现了问题,在我的情况下,浏览器发送的是空 cookie。我仍然无法理解它为什么这样做
    【解决方案2】:

    它是这样工作的,它首先检查相对重定向是否可用,然后构造绝对路径。

      // Generate a temporary redirect to the specified location
        try {
            String locationUri;
            // Relative redirects require HTTP/1.1
            if (getRequest().getCoyoteRequest().getSupportsRelativeRedirects() &&
                    getContext().getUseRelativeRedirects()) {
                locationUri = location;
            } else {
                locationUri = toAbsolute(location);
            }
            setStatus(status);
            setHeader("Location", locationUri);
            if (getContext().getSendRedirectBody()) {
                PrintWriter writer = getWriter();
                writer.print(sm.getString("coyoteResponse.sendRedirect.note",
                        Escape.htmlElementContent(locationUri)));
                flushBuffer();
            }
        } catch (IllegalArgumentException e) {
            log.warn(sm.getString("response.sendRedirectFail", location), e);
            setStatus(SC_NOT_FOUND);
        }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-09-03
      • 1970-01-01
      • 2023-04-01
      • 2014-03-31
      • 2013-06-19
      相关资源
      最近更新 更多