无法正确配置 Intellij Web App 部署

Unable to configure Intellij Web App deployment corrrectly

我正在使用 JSP 和 Servlet、TomCat 9 和 IntelliJ 创建一个 Java 网络应用程序。我正在学习的教程使用 Eclipse,其中讲师只需将项目作为 运行 As > 运行 在服务器上运行,一切都可以无缝运行。

在 IntelliJ 中,事情似乎一团糟。

这是我的项目结构-

这是运行配置-

我将 web.xml 设置为 -

<web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
         version="3.0">
  <display-name>Archetype Created Web Application</display-name>

  <welcome-file-list>
    <welcome-file>login.do</welcome-file>
  </welcome-file-list>

</web-app>

因此,任何对 localhost:8080 的请求,或者在 IntelliJ 的情况下,http://localhost:8080/jspservlet_war_exploded/ 应该重定向到 login.do,由 LoginServlet -[= 处理52=]

package app;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

@WebServlet(urlPatterns = "/login.do")
public class LoginServlet extends HttpServlet {
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {

        String name = req.getParameter("name");
        String pass = req.getParameter("password");
        req.setAttribute("name", name);
        req.setAttribute("password", pass);

        RequestDispatcher requestDispatcher = req.getRequestDispatcher("views/login.jsp");
        requestDispatcher.forward(req, resp);


    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        String name = req.getParameter("name");
        req.setAttribute("name", name);
        RequestDispatcher requestDispatcher = req.getRequestDispatcher("views/welcome.jsp");
        requestDispatcher.forward(req, resp);
    }
}

起初,我在 LoginServlet 中测试 doGet() 方法,只是在起始页 - http://localhost:8080/jspservlet_war_exploded/ 中手动添加 ?name=xxx&password=xxx 查询字符串。这些属性是在 request 中设置的,然后转发到 login.jsp,它只会使用 ${name}${password} 显示属性值。在这一步之前一切正常。

然后,我更改了 login.jsp 页面以包含一个简单的 form,它有一个输入字段来输入用户名,并通过 [=] 将其发送到 /login.do 29=] 属性, 使用 POST 方法 。这就是事情爆发的地方。

这里是 login.jsp -

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<html>
<head>
    <title>Login Page</title>
</head>
<body>
<h1>Welcome</h1>
<p>Time on server is <%= new Date()%></p>
<%--<p>Your name is ${name} and password is ${password}</p>--%>
<p>pageContext.request.contextPath: ${pageContext.request.contextPath}</p>

<form action="/login.do" method="post">
    <label for="inp">Enter your name </label>
    <input id="inp" type="text" name="name"/>
    <button>Submit</button>
</form>
</body>
</html>

结果是这个页面 -

现在,当我点击 "submit" 时,请求似乎转到了 localhost:8080/login.do(因为那是 action 属性的值),这会引发错误 -

根据我在这里读到的其他问题,这似乎是因为上下文路径(即应用程序的根目录)是 http://localhost:8080/jspservlet_war_exploded/,并且所有位置都相对于此路径(? ).所以,推荐的方式似乎是 ${pageContext.request.contextPath}.

基于此,如果我将 action 属性更改为 action="${pageContext.request.contextPath}/login.do",那么一切都会恢复正常。

但是,现在我正在尝试从 LoginServlet 中的 doPost() 方法重定向到 TodoServlet,就像这样 -

resp.sendRedirect("/todo.do");

这又会导致 404,因为 URL 变成了 http://localhost:8080/todo.do,而它应该是 http://localhost:8080/jspservlet_war_exploded/todo.do.

如何修复所有资源默认相对于 http://localhost:8080/jspservlet_war_exploded/ 部署,我可以直接在 action 或 [=46= 中指定 URL 模式]?

你试过这个吗:

resp.sendRedirect("todo.do");

更改 Run/Debug 配置中的部署上下文:

如果您希望应用程序在任何上下文中工作,您应该使用相对路径而不是 described here

而不是 resp.sendRedirect("/todo.do"); 使用 resp.sendRedirect("todo.do");resp.sendRedirect(req.getContextPath() + "/todo.do");