我有以下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()
的“服务”正在登录控制台并且我的线程正常工作,但是我看不到“It Works”从doGet()
被记录,我在浏览器中收到以下错误:
此URL不支持HTTP方法GET
这是如何引起的?如何解决?
答案 0 :(得分:60)
这是HttpServlet#doGet()
默认实现的默认响应。这意味着doGet()
方法不正确地为@Override
n,或者明确地被调用。
您已正确@Override
doGet()
方法,但由于原因不明确,您仍然明确调用默认实现。
super.doGet(req, resp);
摆脱这条线,这个问题就会消失。
HttpServlet
基本上跟随template method pattern,其中所有未覆盖的HTTP方法都返回此HTTP 405错误“Method not supported”。当您覆盖此类方法时,您应该不调用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?
答案 1 :(得分:0)
您已重写service
方法,该方法负责将调用委托给doGet或doPost。 see this for more details
还要从每个方法中删除super.doxxx(..)调用。
不要覆盖service
方法,你应该看到来自doGet的“It Works”。