如何使用注释将 Servlet 操作映射到 JSP 路径?
How to Map Servlet Actions to JSP Path with Annotations?
我有一个简单的 Maven servlet/jsp 应用程序,我将其部署到本地 Tomcat 9(通过 Eclipse)。 JSP 页面存储在根文件夹 (src\main\webapp\*.jsp
) 下,当 Maven 安装 WAR 时,它们位于根文件夹下 (MyAppContext\*.jsp
以及 MyAppContext\META-INF\
和 MyAppContext\WEB-INF\
).
为每个 servlet 注释了 servlet 的 URL 模式,例如/doactionone
、/doactiontwo
等。大多数 servlet 执行对各种 JSP 页面的调度,但我确实有一个直接锚点 link。
我想将这些 JSP 页面移动到它们各自的目录中,所以我将它们移动到 src\main\webapp\jsp\*.jsp
文件夹中,当 Maven 安装为 运行 时,它们被放置在MyAppContext\jsp\
.
我在 web.xml
中的唯一条目是一个欢迎文件,在重新定位 JSP 文件后,它指向 jsp\doactionone.jsp
,它加载相应的 JSP 页面。此页面包含一个简单的表格:
<form action="doactionone" method="post">
...
<a href="jsp/doactiontwo.jsp">
<input type="submit" />...
</form>
此页面上的提交实际上调用了正确的 servlet(用 doactionone
URL 模式定义的那个)。我还有一个 link 将用户带到第二页 (doactiontwo.jsp
)。
然而,当我通过这个 link 导航到第二个页面时,它有另一个简单的形式(见下文),并执行提交 (post),我在浏览器的调试中看到URL 请求是 http://localhost:8080/MyAppContext/jsp/doactiontwo
,出于显而易见的原因,这会 return 404 状态(并且不会命中此 servlet 的 doPost()
(或 doGet()
)方法要么)。
<form action="doactiontwo" method="post">
...
<input type="submit" />...
</form>
如果我尝试将第二个 servlet 的 URL 模式修改为 /jsp/doactiontwo
,我可以命中该 servlet,但是当 doactiontwo
实际上 dispatches/forwards 处理后的请求第一个 servlet (doactionone
) 具有:
RequestDispatcher rd = request.getRequestDispatcher("doactionone.jsp");
rd.forward(request, response);
加载时,将鼠标悬停在最初指向第二个 JSP 页面 (<a href="jsp/doactiontwo.jsp">
) 的第一页上的 URL 上时,现在实际指向:
jsp/jsp/doactiontwo.jsp
搞笑的是,doactionone.jsp的源码还是显示为jsp/doactiontwo.jsp
,但是悬停在上面却显示http://localhost:8080/MyAppContext/jsp/jsp/doactiontwo
,点击的时候,明显是404状态.
有人可以解释为什么首先,第二个 JSP 页面上的提交要求 servlet 具有 /jsp/doactiontwo
模式而不是 /doactiontwo
模式才能工作吗?有没有办法避免将 /jsp
附加到 URL 模式?
其次,为什么当第二个 servlet 处理请求并将其 dispatches/forwards 到第一页时,URL 现在包含两个 jsp/
?
您需要更改设计以允许使用控制器,a.k.a。 Servlet,用于驱动您的应用程序。在这种特殊情况下,使用第二个 Servlet (doactiontwo
) 的 URL 模式代替您 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>
现在,由于调用锚点link时的默认方法是GET
,您需要覆盖DoActionTwoServlet
的doGet()
方法,并将这些请求转发给一个实际的 doactiontwo.jsp
:
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
RequestDispatcher rd = request.getRequestDispatcher("jsp/doactiontwo.jsp");
rd.forward(request, response);
}
我有一个简单的 Maven servlet/jsp 应用程序,我将其部署到本地 Tomcat 9(通过 Eclipse)。 JSP 页面存储在根文件夹 (src\main\webapp\*.jsp
) 下,当 Maven 安装 WAR 时,它们位于根文件夹下 (MyAppContext\*.jsp
以及 MyAppContext\META-INF\
和 MyAppContext\WEB-INF\
).
为每个 servlet 注释了 servlet 的 URL 模式,例如/doactionone
、/doactiontwo
等。大多数 servlet 执行对各种 JSP 页面的调度,但我确实有一个直接锚点 link。
我想将这些 JSP 页面移动到它们各自的目录中,所以我将它们移动到 src\main\webapp\jsp\*.jsp
文件夹中,当 Maven 安装为 运行 时,它们被放置在MyAppContext\jsp\
.
我在 web.xml
中的唯一条目是一个欢迎文件,在重新定位 JSP 文件后,它指向 jsp\doactionone.jsp
,它加载相应的 JSP 页面。此页面包含一个简单的表格:
<form action="doactionone" method="post">
...
<a href="jsp/doactiontwo.jsp">
<input type="submit" />...
</form>
此页面上的提交实际上调用了正确的 servlet(用 doactionone
URL 模式定义的那个)。我还有一个 link 将用户带到第二页 (doactiontwo.jsp
)。
然而,当我通过这个 link 导航到第二个页面时,它有另一个简单的形式(见下文),并执行提交 (post),我在浏览器的调试中看到URL 请求是 http://localhost:8080/MyAppContext/jsp/doactiontwo
,出于显而易见的原因,这会 return 404 状态(并且不会命中此 servlet 的 doPost()
(或 doGet()
)方法要么)。
<form action="doactiontwo" method="post">
...
<input type="submit" />...
</form>
如果我尝试将第二个 servlet 的 URL 模式修改为 /jsp/doactiontwo
,我可以命中该 servlet,但是当 doactiontwo
实际上 dispatches/forwards 处理后的请求第一个 servlet (doactionone
) 具有:
RequestDispatcher rd = request.getRequestDispatcher("doactionone.jsp");
rd.forward(request, response);
加载时,将鼠标悬停在最初指向第二个 JSP 页面 (<a href="jsp/doactiontwo.jsp">
) 的第一页上的 URL 上时,现在实际指向:
jsp/jsp/doactiontwo.jsp
搞笑的是,doactionone.jsp的源码还是显示为jsp/doactiontwo.jsp
,但是悬停在上面却显示http://localhost:8080/MyAppContext/jsp/jsp/doactiontwo
,点击的时候,明显是404状态.
有人可以解释为什么首先,第二个 JSP 页面上的提交要求 servlet 具有 /jsp/doactiontwo
模式而不是 /doactiontwo
模式才能工作吗?有没有办法避免将 /jsp
附加到 URL 模式?
其次,为什么当第二个 servlet 处理请求并将其 dispatches/forwards 到第一页时,URL 现在包含两个 jsp/
?
您需要更改设计以允许使用控制器,a.k.a。 Servlet,用于驱动您的应用程序。在这种特殊情况下,使用第二个 Servlet (doactiontwo
) 的 URL 模式代替您 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>
现在,由于调用锚点link时的默认方法是GET
,您需要覆盖DoActionTwoServlet
的doGet()
方法,并将这些请求转发给一个实际的 doactiontwo.jsp
:
public void doGet(HttpServletRequest req, HttpServletResponse res)
throws ServletException, IOException {
RequestDispatcher rd = request.getRequestDispatcher("jsp/doactiontwo.jsp");
rd.forward(request, response);
}