Issue
I have a simple Maven servlet/jsp application that I deploy to a local Tomcat 9 (via Eclipse). JSP pages are stored under root folder (src\main\webapp\*.jsp
) which when Maven installs a WAR, they go under the root folder (MyAppContext\*.jsp
along side MyAppContext\META-INF\
and MyAppContext\WEB-INF\
).
The servlets' URL patterns are annotated for each servlet, e.g. /doactionone
, /doactiontwo
, etc. Most servlets perform the dispatching to various JSP pages, but I do have a direct anchor link on one.
I wanted to move these JSP pages into their own respective directory, so I moved them to src\main\webapp\jsp\*.jsp
folder, and when the Maven install is run, they get placed under MyAppContext\jsp\
.
The only entry I have in web.xml
is a welcome file that after relocating the JSP files, it points to jsp\doactionone.jsp
which loads that corresponding JSP page. This page contains a simple form:
<form action="doactionone" method="post">
...
<a href="jsp/doactiontwo.jsp">
<input type="submit" />...
</form>
The submission on this page actually calls the right servlet (the one defined with doactionone
URL pattern). I also have a link that takes the user to the second page (doactiontwo.jsp
).
However, when I navigate to that second page via this link, which has another simple form (see below), and perform the submission (post), I see in browser's debugging that the URL request is http://localhost:8080/MyAppContext/jsp/doactiontwo
which, for obvious reason, would return a 404 status (and get no hit to this servlet's doPost()
(or doGet()
) methods either).
<form action="doactiontwo" method="post">
...
<input type="submit" />...
</form>
If I try to modify the second servlet's URL pattern to /jsp/doactiontwo
, I can hit the servlet, but when doactiontwo
actually dispatches/forwards the request after processing to the first servlet (doactionone
) with:
RequestDispatcher rd = request.getRequestDispatcher("doactionone.jsp");
rd.forward(request, response);
when it gets loaded, when hover over the URL on the first page that initially was pointing to the second JSP page (<a href="jsp/doactiontwo.jsp">
), now actually points to:
jsp/jsp/doactiontwo.jsp
The funny part is that the source code of doactionone.jsp still shows it as jsp/doactiontwo.jsp
, but hovering over it shows http://localhost:8080/MyAppContext/jsp/jsp/doactiontwo
, and when clicked, it obviously results in 404 status.
Can somebody explain why, first of all, the submission on the second JSP page requires the servlet to have a pattern of /jsp/doactiontwo
to work rather than /doactiontwo
? And is there a way around to avoid appending /jsp
to the URL pattern?
And second, why when the second servlet processes the request and dispatches/forwards it to the first page, the URL now contains two jsp/
's?
Solution
You need to change your design to allow the controllers, a.k.a. Servlets, to drive your application. In this particular case, use the URL Pattern of second Servlet (doactiontwo
) in place of you link:
@WebServlet(urlPatterns = { "doactiontwo" }
public class DoActionTwoServlet extends HttpServlet { /* ... */ }
<form action="doactionone" method="post">
...
<a href="doactiontwo"> <!-- This should match your second servlet's URL pattern -->
<input type="submit" />...
</form>
Now, since the default method when anchor link is invoked is GET
, you need to overwrite DoActionTwoServlet
's doGet()
method, and forward those requests to an actual doactiontwo.jsp
:
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
RequestDispatcher rd = request.getRequestDispatcher("jsp/doactiontwo.jsp");
rd.forward(request, response);
}
Answered By - Malvon