Double forwarded ServletRequest using RequestDispa

2019-07-25 20:32发布

问题:

My Java web app uses two servlets to control form processing and navigation, /AppControl and /ViewControl.

AppControl processes form submissions, then forwards the request to ViewControl, which determines which page was processed and re-forwards the request to the "next" page.

The first forward (between servlets) works okay; but the second (from ViewControl to the JSP page) malforms the URL, and I get a 404.

The servlets are both mapped to root of context, the JSP files are in a subfolder named /view/

Forward #1 goes from /AppControl to /ViewControl, and forward #2 goes from /ViewControl to /view/xxx.jsp, but what appears in browser is localhost:8080/view//view/xxx.jsp, which is obviously not where it should've gone. Notice the context is missing from the URL sent to the browser, and an extra instance of the string "/view/" is being embedded.

I've tried:

  • switching between using ServerContext and ServerRequest for the RequestDispatcher
  • using absolute and relative paths ("./" -- is that a valid relative path?)
  • attaching (pre-pending) the contextPath to the URL

and various other hacks and gyrations, but nothing seems to make it work; it keeps changing the URL sent to the browser to something other than the URL which appears in debug (assoc'd with RD).

BTW, the request originates from (referrer?) localhost:8080/(context)/view/zzz.jsp, POSTed to /AppControl;

I'm using getServletContext().getRequestDispatcher(java.lang.String) to forward, so I was under the impression that the target resource is relative to the root of the context.

Here's what I've tried, and the results I've had:

URL String Param     | Resulting URL
---------------------|---------------
 /view/xxx.jsp       | localhost:8080/view//view/xxx.jsp
 ./xxx.jsp           | localhost:8080/myApp/xxx.jsp
 ./view/xxx.jsp      | localhost:8080/view/view/xxx.jsp
 /myApp/view/xxx.jsp | localhost:8080/myApp/myApp/view/xxx.jsp

I'll follow up this post with actual code, and maybe screenshots (if I can do that)... my environment:

  • Java 6.0_34
  • Eclipse Juno (4.2.0)
  • Tomcat 7.0.21.

code:

            //get page navigation info
            setNavigation();
            session.setAttribute("viewControl", this.pageNext);

            //navigate to this.pageNext
            //response.sendRedirect(this.pageNext);
            pageForward(request, response, this.pageNext);
        }
    }else {
        pageForward(request, response, this.appStartPage);
    }
}

private void pageForward(HttpServletRequest request, HttpServletResponse response, String url) 
throws ServletException, IOException {
    RequestDispatcher rd = getServletContext().getRequestDispatcher(url);
    //RequestDispatcher rd = request.getRequestDispatcher(url);

    rd.forward(request, response);
}

private void setNavigation() {
    //this.urlViewBase = this.urlAppBase + "/view/";
    this.urlViewBase = "/view/";
    //this.urlViewBase = "./";
    //this.urlViewBase = "./view/";

    if (this.pageCurrent.equals("StartView.jsp")) {
        this.pageNext = this.urlViewBase + "ApplicantInfo.jsp";
        this.pagePrevious = this.urlViewBase + "StartView.jsp";
    }
    else if (this.pageCurrent.equals("ApplicantInfo.jsp")) {
        this.pageNext = this.urlViewBase + "ApplicantAddress.jsp";
        this.pagePrevious = this.urlViewBase + "StartView.jsp";
    }
    else if (this.pageCurrent.equals("ApplicantAddress.jsp")) {
        this.pageNext = this.urlViewBase + "Menu.jsp";
        this.pagePrevious = this.urlViewBase + "ApplicantInfo.jsp";
    }
    else if (this.pageCurrent.equals("Menu.jsp")) {
        this.pageNext = this.urlViewBase + "Menu.jsp";
        this.pagePrevious = this.urlViewBase + "ApplicantAddress.jsp";
    }
    else {
        this.pageNext = this.urlViewBase + "StartView.jsp";
        this.pagePrevious = this.urlViewBase + "StartView.jsp";
    }
}