我一直致力于在我的电子商务应用程序中实施Punchout
。我的实现如下:
直到昨天一切正常,然后当重定向到商店前端时,会话开始掉线。
重定向发生前HttpServletRequest
对象为RequestFacade
,但在重定向后,它变为ApplicationHttpRequest
。我可以找到包裹在RequestFacade
中的ApplicationHttpRequest
,但我找不到我在会话中放置的对象。下面是我用来将对象放在会话中的函数。
/**
* 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()
的错误值来弄乱它,所以我评论了它。令我惊讶的是,无论如何,会议都被放弃了。
Apache Tomcat
上使用Windows 8.1
。 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中。
为什么HttpServletRequest对象会发生变化。
HttpServletRequest更改为ApplicationHttpRequest
HttpServletRequest to ApplicationHttpRequest
Spring ServletRequest对象更改
重定向后HttpServletRequest更改
自从过去3天以来,这个愚蠢的错误让我们感到沮丧。任何帮助,将不胜感激!请指出我所犯的任何愚蠢错误,并且一些与会话处理/管理相关的好提示是最受欢迎的。如果您认为我没有提供足够的信息,请同时指出。谢谢:))
答案 0 :(得分:1)
是的,我正在回答我自己的问题。我希望详细介绍,以便未来的人可以找到答案。
原来我是一个重定向到绝对路径的白痴。
无论您重定向的servlet是驻留在同一个应用程序服务器上,都在同一个应用程序中,或者它甚至共享同一个servlet。 重定向到绝对路径的任何请求都有自己的上下文!因此,为它们创建的请求对象是全新的,并且具有单独的会话。只有在同一port
,host
和{{1}上发送重定向时,才会维护会话。 }。 如果在同一个应用程序中完成重定向,则使用相对路径使用相对路径是最佳做法。
从webapp
重定向到https://localhost/servlet1.html
是非常不同的,即使URL映射到同一个servlet(请注意区别)。
从http://localhost/servlet2.html
重定向到https://localhost/servlet1.html
或https://192.168.x.x/servlet2.html
会产生相同的结果。
此处的最佳做法是重定向到相对于您的应用程序的路径 。这将以最有效的方式共享会话对象。
使用https://127.0.0.1/servlet2.html
是最好的事情(在我看来)。
会话由response.sendRedirect("servlet2.html");
Cookie标识。如果浏览器转发此cookie,则会话转发到另一个servlet或控制器(或其他)。 JSESSIONID
和HTTP
是不同的协议,因此使用不同的Cookie。同样,HTTPs
和IP地址是浏览器的不同主机,因此使用不同的cookie。如果localhost
,JSESSIONID
和protocol
保持不变,则会转发host
Cookie,但这与使用重定向中的相对路径具有相同的含义。重定向到相对地址可以被认为是在同一主机,协议和应用程序上下文上重定向的安全方式。 浏览器决定是否要转发您的webapp context
Cookie
答案 1 :(得分:0)
这是它的工作方式,它首先检查相对重定向是否可用,然后构造绝对路径。
// 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);
}