2014-12-10 5 views
0

저는 매우 오래된 J2EE/struts 사이트에서 작업하고 있으며 최근에 PayPal에서 SSL 3 프로토콜 지원 중단으로 인해 새로운 호스트 체크 아웃 프로세스를 구현하려고합니다. 지불 게이트웨이는 주문 세부 정보가 포함 된 POST를 수락하고 신용 카드 유효성 검사를 처리하며 다른 POST를 통해 응답 코드 (및 기타 다른 값)를 반환합니다.Struts 액션이 컨트롤러 변경 후 올바른 경로를 렌더링하지 않습니다.

struts에서 기존 작업을 활용하려하지만 struts-config.xml에 지정된 경로 (/store/order/confirmation.do)이 렌더링되지 않기 때문에 중단됩니다. 대신 원격 서버의 POST 요청이 처리되고 ActionMapping.findForward()가 호출 된 후 응용 프로그램은 POST에서 원격 서버의 요청과 동일한 경로를 렌더링합니다. (/store/checkout/submitOrder.do).

struts-config.xml에서 forward에 redirect = "true"를 추가하려고하면 올바른 경로로 리디렉션되지만 pagecontext 예외가 발생하여 로그되지 않아 디버깅 할 수 없습니다.

작동 방식은 submitOrder 양식이 비어있는 것입니다. 단지 제출 입력입니다. 그런 다음 세션 기반 쇼핑 카트 및 관련 고객 청구서의 체크 아웃 세부 정보가 특수한 버전 라이브러리로 전달되어 응답을 생성합니다. 이제 새 공급자의 POST 양식을 사용하려고하지만이 리디렉션 실패로 인해 막혔습니다.

스트럿 - 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 매개 변수가 뭔가를 오염시키고 적절한 라우팅을 방해하는지 궁금합니다.

타일 - 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 뷰를 제공하지만/저장/주문/확인 라우팅되지 .do가 없으므로 페이지를 다시로드하려고하면 양식을 다시 제출하라는 메시지가 표시됩니다. 이는 분명히 바람직하지 않습니다.

struts-config.xml에 submitOrder 액션 정의에서 name = "emptyForm"에 대한 참조를 삭제했습니다. (원격 서버에서 오는 POST 양식은 emptyForm 이름 속성을 갖지 않으므로) :

나는 어느 효과가 있을지 모르겠습니다.

+0

나는 완전히 틀렸어. 모든 것이 적절하게 전달됩니다! 나는 라우팅이 /store/order/confirmation.do를 해결할 것이라고 생각했지만 실제로 submitOrder.do로가는 것으로되어있다! – Thom

답변

0

전달을 사용하면 클라이언트는 요청한 리소스 (submitOrder.do)를 더 이상 알 수 없기 때문에 항상 요청한 리소스를보고 있다고 생각합니다. 즉, 리소스에 대해 단일 요청이 이루어지고 응답이 다시 돌아 왔기 때문입니다. 응답 내용 은 앞으로 자원 (confirmation.do)에서 오는 일 것입니다.

응답 내용이 이 아니고confirmation.do 인 경우 다른 문제가 있습니다. 이 경우 PayPal 콜백이 POST와 다른 요청 방법을 사용하고있을 가능성이 가장 높습니다. 이는 submitOrder() 코드 (// HTTP method was not POST)의 대부분을 우회합니다. confirmation.do 뒤에있는 Struts 액션에는 필요한 세션이나 요청 속성이 누락되어 submitOrder 페이지가 표시됩니다.

+0

정말 고마워요! 다시 말하자면, 1) 결제 서비스에 데이터를 POST하고, 2) 결제 서비스가 고객 입력 (신용 카드/기프트 카드/등)을 처리하고, 3) 결제 서비스에서 /submitOrder.do에 POST를 실행합니다. - 결제 서비스의 양식을 Google의 사이트 소스로 복사했습니다. POST 요청인지 확인하기 위해서입니다. client.saveOrder() 메소드 호출이 잘 작동하기 때문에 submitOrder 액션을 우회하지 않는다는 것을 안다. 일단 POST 요청이 처리되면 confirm.do의 해결책 만있는 것 같다. – Thom

+0

응답 내용 (tiles-defs.xml에 정의 된 '/store/checkout/confirmOrder.jsp')이 제공되고 있음을 언급하는 것을 잊었습니다. /confirmation.do 경로로 라우팅되지 않았으므로 페이지를 새로 고침하거나 기존 방법을 통해 원본을보고 사용자에게 양식을 다시 제출하라는 메시지를 표시합니다. – Thom

+0

좋아, 문제를 해결하는 가장 간단한 방법은 다음과 같습니다. 나는 보통 세션에 가중치를 추가하는 것을 권장하지 않겠지 만,'scope' 폼을 strutsConfig.xml에서 요청하는 것이 아니라 session으로 지정한다면, submitOrder.do와 confirm.do 모두에 대해, "shoppingCart" 속성 (요청에 따라 이동하지 마십시오)이 confirm.do에 의해 정리되도록하려면, 성공하면 redirect = "true"를 안전하게 설정할 수 있습니다. – gknicker