【问题标题】:HTTP Status 405 - HTTP method is not supported by this URLHTTP 状态 405 - 此 URL 不支持 HTTP 方法
【发布时间】:2011-07-19 05:50:36
【问题描述】:

我有以下 servlet:

public class MyServlet extends HttpServlet {

    private static final long serialVersionUID = 16252534;
    private static int ping = 3000;
    private Thread t;
    private static boolean shouldStop = false;

    @Override
    public void init() throws ServletException {
        super.init();

        t = new Thread(new Runnable() { 
            @Override
            public void run() {
                while(!shouldStop) {
                    System.out.println("Now:" + System.currentTimeMillis());
                    try {
                        Thread.sleep(ping);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            }
        });
        t.start();

    }
    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp)
    throws ServletException, IOException {
        super.doGet(req, resp);
        System.out.println("doGet");
        PrintWriter out = resp.getWriter();
        out.println("<html><h1>It works!!</h1></html>");
    }

    @Override
    public void service(ServletRequest req, ServletResponse resp) throws ServletException, IOException {
        super.service(req, resp);
        System.out.println("service");

    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        super.doPost(req, resp);
        System.out.println("doPost");

    }

    @Override
    public void destroy() {
        super.destroy();
        System.out.println("Destroy servlet");
        shouldStop = true;
    }
}

在我的web.xml中映射如下:

<display-name>MyServer</display-name>
<welcome-file-list>
    <welcome-file>index.jsp</welcome-file>
</welcome-file-list>

<servlet>
    <servlet-name>MyServlet</servlet-name>
    <servlet-class>com.myserver.MyServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>      
   <servlet-mapping>
    <servlet-name>MyServlet</servlet-name>
    <url-pattern>/MyServlet</url-pattern>
</servlet-mapping>

当我在 http://localhost:8080/MyServer/MyServlet 上打开我的浏览器 (Chrome) 时,我看到来自 doService() 的“服务”正在登录控制台,并且我的线程正常工作,但是我没有看到来自 doGet() 的“它工作”被记录,我在浏览器中收到以下错误:

此 URL 不支持 HTTP 方法 GET

这是怎么引起的,我该如何解决?

【问题讨论】:

    标签: servlets http-get http-status-code-405


    【解决方案1】:

    这是HttpServlet#doXxx()方法(doGet()doPost()doHead()doPut()等)的默认实现的默认响应。这意味着,当 doXxx() 方法在您的 servlet 类中不正确地被 @Overriden 或通过 super 显式调用时,您将面临 HTTP 405“不允许的方法”错误。

    因此,您需要确保正确声明的 doXxx() 方法符合 API,包括 @Override 注释,以确保您没有输入任何拼写错误。例如

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        // ...
    }
    

    您还需要确保您永远不会在您的 servlet 方法中调用 super.doXxx()

    super.doGet(request, response);
    

    你的 servlet 有这个。只要去掉这条线,你的问题就会消失。

    HttpServlet 基本上遵循template method pattern,其中所有未覆盖的 HTTP 方法都返回此 HTTP 405 错误“方法不受支持”。当您覆盖这样的方法时,您应该调用super 方法,否则您仍然会收到 HTTP 405 错误。您的 doPost() 方法也会发生同样的情况。

    顺便说一句,这也适用于service(),但从技术上讲,这不会对这个结构造成伤害,因为您需要它让默认实现执行正确的方法。实际上,整个 service() 方法对你来说是不必要的,你可以从你的 servlet 中删除整个方法。

    super.init(); 也是不必要的。仅当您覆盖 init(ServletConfig) 时才需要这样做,否则不会设置 ServletConfig。这也是javadoc明确提到的。这是唯一需要super 调用的方法。


    与具体问题无关,在这样的 servlet 中生成线程是个坏主意。对于正确的方法,前往How to run a background task in a servlet based web application?

    【讨论】:

    • 非常感谢。我用过 ServletContextListener。一个问题:为什么在 servlet 中使用 Thread 是个坏主意?
    • 这不一定是坏事,但是您编写代码的方式会永远消耗 100% 的 CPU 资源。您应该使用链接答案中概述的线程池和调度程序。 ServletContextListener 是在 webapp 启动和关闭期间进行全局初始化和清理的正确位置。
    【解决方案2】:

    您已经覆盖了负责将调用委托给 doGet 或 doPost 的 service 方法。 see this for more details
    还要摆脱每个方法的 super.doxxx(..) 调用。 不要覆盖 service 方法,您应该会看到来自 doGet 的“It Works”。

    【讨论】:

      猜你喜欢
      • 2023-03-29
      • 2012-12-14
      • 2021-05-21
      • 2016-01-03
      • 2015-03-10
      • 2015-03-11
      • 2016-02-13
      相关资源
      最近更新 更多