我正在使用JSP和Servlet,TomCat 9和IntelliJ创建Java Web应用程序。我正在学习的教程使用Eclipse,讲师仅以Run As> Run On Server的身份运行项目,并且一切工作均无缝进行。
在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
-
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);
}
}
首先,我只是通过在开始页面doGet()
中手动添加LoginServlet
查询字符串来测试?name=xxx&password=xxx
中的http://localhost:8080/jspservlet_war_exploded/
方法。这些属性在request
中设置,然后转发到login.jsp
,后者将仅使用${name}
和${password}
显示属性值。一切正常,直到这一步。
然后,我将login.jsp
页面更改为包括一个简单的form
,该页面具有用于输入用户名的输入字段,并将其通过{{1}发送到/login.do
}属性,使用action
方法。这是爆炸的地方。
这里是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>
(因为这就是localhost:8080/login.do
属性的值),并且引发了错误-
基于我在这里阅读的其他问题,由于上下文路径(即应用程序的根目录)是action
,并且所有位置都相对于该路径(?),因此似乎发生了这种情况。因此,推荐的方法似乎是http://localhost:8080/jspservlet_war_exploded/
。
基于此,如果我将${pageContext.request.contextPath}
属性更改为action
,那么事情将再次起作用。
但是,现在我正尝试从action="${pageContext.request.contextPath}/login.do"
中的doPost()
方法重定向到LoginServlet
,就像这样-
TodoServlet
由于URL变为resp.sendRedirect("/todo.do");
,而应为http://localhost:8080/todo.do
,因此这再次导致404。
如何解决问题,以便默认情况下所有资源都相对于http://localhost:8080/jspservlet_war_exploded/todo.do
进行部署,并且我可以直接在http://localhost:8080/jspservlet_war_exploded/
或action
中指定URL模式?
答案 0 :(得分:0)
您尝试过这个吗?
resp.sendRedirect("todo.do");
答案 1 :(得分:0)
在“运行/调试”配置中更改部署上下文:
如果您希望应用程序可在任何上下文中使用,则应使用相对路径,例如described here。
使用resp.sendRedirect("/todo.do");
或resp.sendRedirect("todo.do");
代替resp.sendRedirect(req.getContextPath() + "/todo.do");