23

我有以下 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>

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

此 URL 不支持 HTTP 方法 GET

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

4

2 回答 2

64

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

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

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

而且你还需要确保你永远不会调用super.doXxx()你的 servlet 方法:

super.doGet(request, response);

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

HttpServlet基本上遵循模板方法模式,其中所有未覆盖的 HTTP 方法都返回此 HTTP 405 错误“方法不支持”。当你覆盖这样的方法时,你不应该调用方法super,否则你仍然会得到 HTTP 405 错误。同样的故事也发生在你的doPost()方法上。

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

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


与具体问题无关,在这样的 servlet 中生成线程是个坏主意。对于正确的方法,请前往如何在基于 servlet 的 Web 应用程序中运行后台任务?

于 2011-03-20T19:06:48.063 回答
0

您已经覆盖了service负责将调用委托给 doGet 或 doPost 的方法。有关更多详细信息,请参阅此内容
还可以摆脱每个方法的 super.doxxx(..) 调用。不要重写该service方法,您应该会从 doGet 中看到“It Works”。

于 2011-03-20T19:07:26.573 回答