次のサーブレットがあります。
_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()
がログに記録され、ブラウザに次のエラーが表示されます:
HTTPメソッドGETはこのURLではサポートされていません
これはどのように引き起こされ、どのように解決できますか?
これは、HttpServlet#doGet()
のデフォルト実装のデフォルト応答です。これは、doGet()
メソッドが正しく_@Override
_ nになっていないか、明示的に呼び出されていることを意味します。
_@Override
_ doGet()
メソッドを適切に実行しましたが、理由が明確でないため、デフォルトの実装を明示的に呼び出しています。
_super.doGet(req, resp);
_
この行を取り除くと、この問題は解消されます。
HttpServlet
は基本的に template method pattern に従います。オーバーライドされていないすべてのHTTPメソッドがこのHTTP 405エラー「メソッドはサポートされていません」を返します。このようなメソッドをオーバーライドする場合は、HTTP 405エラーが発生するため、super
メソッドをnotで呼び出す必要があります。 doPost()
メソッドについても同じことが言えます。
ちなみにこれはservice()
にも当てはまりますが、デフォルトの実装で適切なメソッドを実行するにはが必要なので、技術的にはこの構成に害はありません。実際には、service()
メソッド全体は不要です。サーブレットからメソッド全体を削除できます。
super.init();
も不要です。 init(ServletConfig)
をオーバーライドする場合にのみ必要です。そうしないと、ServletConfig
が設定されないためです。これも javadoc で明示的に言及されています。 super
呼び出しを必要とする唯一のメソッドです。
具体的な問題とは無関係、そのようなサーブレットでスレッドを生成することは悪い考えです。正しいアプローチについては、 サーブレットベースのWebアプリケーションでバックグラウンドタスクを実行する方法に進んでください。
doGetまたはdoPostの呼び出しを委任するservice
メソッドをオーバーライドしました。 詳細はこちらをご覧ください
また、各メソッドからのsuper.doxxx(..)呼び出しを削除します。 service
メソッドをオーバーライドしないでください。doGetの「It Works」が表示されます。