HTTP Status 405 - HTTP-метод GET не поддерживается этим URL-адресом

У меня есть следующий сервлет:

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>

Когда я открываю свой браузер (Chrome) на http://localhost:8080/MyServer/MyServlet, я вижу, что "service" из doService() записывается на консоль, и мой поток работает правильно, однако я не вижу "It Works" из doGet() и я получаю следующую ошибку в браузере:

HTTP-метод GET не поддерживается этим URL-адресом

Как это вызвано и как я могу его решить?

Ответ 1

Это ответ по умолчанию реализации по умолчанию HttpServlet#doGet(). Это означает, что метод doGet() не является надлежащим образом @Override n или явно вызывается.

Вы правильно выполнили @Override метод doGet(), но вы по-прежнему явно вызываете реализацию по умолчанию по непонятной причине.

super.doGet(req, resp);

Избавьтесь от этой строки, и эта проблема исчезнет.

HttpServlet в основном следует шаблону шаблон шаблона, где все непереопределенные HTTP-методы возвращают эту ошибку HTTP 405 "Метод не поддерживается", Когда вы переопределяете такой метод, вы должны не вызывать метод super, потому что в противном случае вы все равно получите ошибку HTTP 405. Эта же история продолжается и для вашего метода doPost().

Это также относится к service() кстати, но это технически не вредит в этой конструкции, так как вам нужно, чтобы реализация по умолчанию выполняла правильные методы. На самом деле, весь метод service() не нужен для вас, вы можете просто удалить весь метод из своего сервлета.

super.init(); также не требуется. Это необходимо, только если вы переопределите init(ServletConfig), потому что иначе ServletConfig не будет установлен. Это также явно упоминается в javadoc. Это единственный метод, который требует вызова super.


Несвязанный к конкретной проблеме, порождение потока в таком сервлете - плохая идея. Для правильного подхода перейдите в Как выполнить фоновое задание в веб-приложении на сервлетах?

Ответ 2

вы переопределили метод service, который отвечает за делегирование вызова doGet или doPost. см. это для более подробной информации
Также избавляйтесь от вызовов super.doxxx(..) от каждого метода. Не переопределяйте метод service, и вы должны увидеть "Работает" из doGet.