我在一个Java Servlet Web应用程序上工作,我想创建一个管理登录。为此,我使用Map/management/login
呈现登录页面,并使用相同的路由发送登录请求。两者都使用相同的LoginController
,但我在那里定义了doGet
和doPost
方法。doGet
工作正常,但当我点击登录它也来到doPost
方法,但呈现,
HTTP Status 405 – Method Not Allowed
Type: Status Report
Message: HTTP method POST is not supported by this URL
Description: The method received in the request-line is known by the origin server but not supported by the target resource.
Apache Tomcat/10.1.8
我只想在登录表单下面呈现错误消息。
我参考了几个Stack Overflow的答案,但没有一个对我有用。
下面是我的代码,
LoginController.java
public class LoginController extends ControllerBase {
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
if (isAuthenticated(req)) {
res.sendRedirect("/management/dashboard");
return;
}
RequestDispatcher dispatcher = req.getRequestDispatcher("WEB-INF/views/management/login.jsp");
dispatcher.forward(req, res);
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
String email = req.getParameter("email");
String password = req.getParameter("password");
if (Utils.isNullOrEmpty(email) || Utils.isNullOrEmpty(password)) {
req.setAttribute("error", "Invalid credentials");
RequestDispatcher dispatcher = req.getRequestDispatcher("WEB-INF/views/management/login.jsp");
dispatcher.forward(req, res);
return;
}
login(req);
Console.log("User logged in");
res.sendRedirect("/management/dashboard");
}
}
Login.jsp
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" isELIgnored="false" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="t" tagdir="/WEB-INF/tags" %>
<t:public_layout>
<jsp:attribute name="title" trim="true">Management Login</jsp:attribute>
<jsp:body>
<div class="container p-5">
<div class="row">
<div class="col-md-8">
<h4>
Management Login
</h4>
<p>
Welcome back! Sign in to your account to access all the features.
</p>
</div>
<div class="col-md-4">
<form action="/management/login" method="post">
<div class="mb-3">
<label for="email" class="form-label">Email address</label>
<input type="email" class="form-control" name="email" id="email" placeholder="[email protected]"
autocomplete="username">
</div>
<div class="mb-3">
<label for="password" class="form-label">Password</label>
<input type="password" class="form-control" name="password" id="password" placeholder="Password"
autocomplete="current-password">
</div>
<div class="mb-3">
<button type="submit" class="btn btn-primary w-100">Sign in</button>
</div>
<c:if test="${not empty error}">
<div class="alert alert-danger" role="alert">
${error}
</div>
</c:if>
</form>
</div>
</div>
</div>
</jsp:body>
</t:public_layout>
web.xml
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>HomeController</servlet-name>
<display-name>HomeController</display-name>
<description>HomeController</description>
<servlet-class>com.dinindu.oas.controller.HomeController</servlet-class>
</servlet>
<servlet>
<servlet-name>ManagementController</servlet-name>
<display-name>ManagementController</display-name>
<description>ManagementController</description>
<servlet-class>com.dinindu.oas.controller.management.ManagementController</servlet-class>
</servlet>
<servlet>
<servlet-name>ManagementLoginController</servlet-name>
<display-name>ManagementLoginController</display-name>
<description>ManagementLoginController</description>
<servlet-class>com.dinindu.oas.controller.management.LoginController</servlet-class>
</servlet>
<servlet>
<servlet-name>ManagementDashboardController</servlet-name>
<display-name>ManagementDashboardController</display-name>
<description>ManagementDashboardController</description>
<servlet-class>com.dinindu.oas.controller.management.DashboardController</servlet-class>
</servlet>
<servlet>
<servlet-name>LogoutController</servlet-name>
<display-name>LogoutController</display-name>
<description>LogoutController</description>
<servlet-class>com.dinindu.oas.controller.LogoutController</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>HomeController</servlet-name>
<url-pattern/>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ManagementController</servlet-name>
<url-pattern>/management/*</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ManagementLoginController</servlet-name>
<url-pattern>/management/login</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>ManagementDashboardController</servlet-name>
<url-pattern>/management/dashboard</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>LogoutController</servlet-name>
<url-pattern>/logout</url-pattern>
</servlet-mapping>
<servlet-mapping>
<servlet-name>default</servlet-name>
<url-pattern>/assets/*</url-pattern>
</servlet-mapping>
</web-app>
1条答案
按热度按时间ttp71kqs1#
问题出在这一部分
Url模式
/management/*
与请求url/management/login
匹配,并且出现在web.xml中ManagementLoginController
servlet的servletMap之前。因此ManagementController
是负责处理请求的servlet。下面是Servlet 2.5规范第SRV.11章的摘录:
用于Map到servlet的路径是来自请求对象的请求URL减去上下文路径和路径参数。下面的URL路径Map规则按顺序使用。使用第一个成功的匹配,不再尝试其他匹配:
1.容器将尝试查找请求路径与servlet路径的精确匹配。成功的匹配选择servlet。
1.容器将递归地尝试匹配最长的路径前缀。这是通过使用“/”字符作为路径分隔符,一次一个目录地向下步进路径树来完成的。最长的匹配决定了所选的servlet。
1.如果URL路径中的最后一段包含扩展名(例如,.jsp),则servlet容器将尝试匹配处理扩展请求的servlet。扩展名定义为最后一个段中最后一个“.”字符之后的部分。
1.如果前面三个规则都没有产生servlet匹配,容器将尝试为所请求的资源提供适当的内容。如果为应用程序定义了一个“默认”servlet,则将使用它。
希望它能帮助