Java Servlet HTTP 状态 405 不允许方法

问题描述 投票:0回答:1

我正在开发一个 Java Servlet Web 应用程序,我想在其中创建管理登录名。为此,我使用映射

/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");
    }
}

登录.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>

servlets http-status-code-405 servlet-mapping
1个回答
3
投票

问题出在这部分

<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>

Url 模式

/management/*
与请求 url
/management/login
匹配,并出现在 web.xml 中
ManagementLoginController
servlet 的 servlet 映射之前。因此
ManagementController
是负责处理请求的 servlet。

以下是 Servlet 2.5 规范章节 SRV.11 的摘录:

用于映射到 servlet 的路径是来自 servlet 的请求 URL 请求对象减去上下文路径和路径参数。网址 下面的路径映射规则按顺序使用。第一次成功匹配 使用时不再尝试进一步匹配:

  1. 容器将尝试找到请求路径与 servlet 路径的精确匹配。成功匹配选择 servlet。
  2. 容器将递归地尝试匹配最长的路径前缀。这是通过沿着路径树向下移动一个目录来完成的 一次使用“/”字符作为路径分隔符。最长的 匹配确定选择的 servlet。
  3. 如果 URL 路径中的最后一段包含扩展名(例如 .jsp),servlet 容器将尝试匹配处理 请求延期。扩展被定义为 最后一个“.”字符之后的最后一段。
  4. 如果前三个规则都没有导致 servlet 匹配,则容器将尝试提供适合该 servlet 的内容 请求资源。如果定义了“默认”servlet 应用,就会被使用。

希望有帮助

© www.soinside.com 2019 - 2024. All rights reserved.