我正在一个非常古老的J2EE / struts网站上工作,由于PayPal最近停止了对SSL 3协议的支持,我正在尝试实施一个新的托管结账流程,支付网关接受该流程带有订单详细信息的POST,处理信用卡验证,并通过另一个POST返回响应代码(以及一百万个其他值)。
我试图利用struts中的现有操作,但是因为struts-config.xml (/ store / order / confirmation.do)中指定的路径而挂起了没有被渲染;相反,在处理来自远程服务器的POST请求并调用ActionMapping.findForward()之后,应用程序只返回从远程服务器返回POST中请求的相同路径(/ store / checkout / submitOrder 。做)
如果我尝试添加redirect =" true"对于struts-config.xml中的forward,我被重定向到正确的路径,但是由于没有记录,我无法调试pagecontext异常。
以前的工作方式是submitOrder表单是空的 - 只是一个提交输入。然后,来自基于会话的购物车和关联的客户填充表格的结账详细信息将被移交给特殊的verisign库以生成响应。我现在想要使用来自新提供程序的表单POST,但我仍然坚持这个重定向惨败。
struts-config.xml中的行如下所示:
<action path="/store/checkout/submitOrder" type="com.company.action.CheckoutAction" parameter="submitOrder" scope="request">
<set-property property="secure" value="true"/>
<forward name="success" path="/store/order/confirmation.do"/>
</action>
行动就是这样:
public ActionForward submitOrder(ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response) throws Exception {
String method = request.getMethod();
if (method != null && method.equals("POST")) {
ShoppingCart sc = (ShoppingCart) request.getSession(false).getAttribute("shoppingCart");
if (sc == null) { throw new SessionExpiredException("Submit Order - Shopping Cart is not in session"); }
ResourceBundle appConfig = ResourceBundle.getBundle("resources.application");
PFProClient client = new PFProClient();
/* THIS saveOrder() METHOD WAS RE-WRITTEN TO TAKE the httpservletrequest (form POST) instead of an instance of VerisignResponse, defined in another library. */
client.saveOrder(sc, request);
User user = (User)request.getSession(false).getAttribute(Globals.USER);
if (user != null) { UserModel.saveUser(user, sc.getCustomer(), sc.getOrder()); }
//Remove items from session
request.getSession().setAttribute("customerBillingForm", null);
request.getSession().setAttribute("customerShippingForm", null);
request.getSession().setAttribute("customerCreditForm", null);
request.getSession().setAttribute("cartForm", null);
request.getSession().setAttribute("shoppingCart", null);
//remove the shopping cart from the cookie & DB
ShoppingCartUtils.deleteSavedCartFromCookie(response, request);
//remove the CHECKING_OUT flag
request.getSession().setAttribute(Globals.CHECKING_OUT, null);
//remove the PAYING_WITH_PAYPAL flag
request.getSession().setAttribute(Globals.PAYING_WITH_PAYPAL, null);
// Set cart in request for order confirmation page
request.setAttribute("shoppingCart", sc);
return mapping.findForward("success");
} else {
// HTTP method was not POST
}
return mapping.findForward("success");
}
修改
我已经验证了submitOrder操作正在作为POST请求进行处理。我想知道,由于之前的POST只是一个空表格,额外的POST参数会使某些事情变得严重,并阻止正确的路由。
在tiles-defs.xml中,confirmation.do视图的资源是:
<definition name="confirm.order" path="/templates/layouts/order-confirmation.jsp">
...
<put name="content" value="/store/checkout/confirmOrder.jsp"/>
</definition>
应用程序正在提供 confirmOrder.jsp 视图,但没有路由到/store/order/confirmation.do,因此任何重新加载页面的尝试都会提示用户重新提交表单,这是显然不受欢迎。
我还删除了对name =&#34; emptyForm&#34;的引用。来自submitOrder操作定义(因为来自远程服务器的表单POST不具有emptyForm name属性)在struts-config.xml中定义为:
<form-bean name="emptyForm" type="org.apache.struts.action.DynaActionForm"/>
我不确定会有什么影响。
答案 0 :(得分:0)
对于转发,客户将始终认为它仍在查看所请求的资源(submitOrder.do
),因为它无法更好地了解(即单个请求已被提出)对于资源和响应回来了)。响应内容应来自转发资源(confirmation.do
)。
如果来自confirmation.do
的回复内容不,那么我们正在查看其他问题。在这种情况下,PayPal回调最有可能使用与POST不同的请求方法,后者将绕过大多数submitOrder()
代码(// HTTP method was not POST
)。而confirmation.do
后面的Struts Action缺少必要的会话或请求属性,可能会显示submitOrder页面。