2011-03-20 19 views
18

Tengo el siguiente servlet:HTTP Status 405 - método HTTP GET no es compatible con esta 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; 
    } 
} 

la que se asigna de la siguiente manera en mi 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> 

Cuando abro mi navegador (Chrome) en http://localhost:8080/MyServer/MyServlet, luego veo que el "servicio" de doService() está conectado a la consola y mi hilo funciona correctamente, sin embargo, no veo "Funciona" desde doGet() que se registra y aparece el siguiente error en el navegador:

Método

HTTP GET no es compatible con este URL

¿Cómo se hizo y cómo lo puedo resolver?

Respuesta

54

Esta es la respuesta predeterminada de la implementación predeterminada de HttpServlet#doGet(). Esto significa que el método doGet() no está siendo correctamente @Override n, o se está llamando explícitamente.

Has hecho correctamente @Override el método doGet(), pero sigues llamando explícitamente a la implementación predeterminada por motivos poco claros.

super.doGet(req, resp); 

Deshágase de esta línea y este problema desaparecerá.

El HttpServlet básicamente sigue el template method pattern donde todos los métodos HTTP no reemplazados devuelven este error HTTP 405 "Método no admitido". Cuando anula dicho método, debe no llamar al método super, ya que de lo contrario seguirá recibiendo el error HTTP 405. La misma historia continúa para su método doPost().

Esto también se aplica en service() por cierto, pero que técnicamente no dañen en esta construcción, ya que necesidad a dejar que la aplicación por defecto ejecutar los métodos apropiados. En realidad, el método completo service() es innecesario para usted, solo puede eliminar todo el método de su servlet.

El super.init(); tampoco es necesario. Solo es necesario cuando anula el init(ServletConfig), porque de lo contrario el ServletConfig no se configuraría. Esto también es explícitamente mencionado en el javadoc. Es el único método que requiere una llamada super.


Sin relación al problema concreto, se generaba un subproceso en un servlet como que es una mala idea. Para el enfoque correcto, diríjase a How to run a background task in a servlet based web application?

+0

Muchas gracias. He usado ServletContextListener. Una pregunta: ¿por qué usar Thread en servlet es una mala idea? – CeccoCQ

+1

No es necesariamente malo, pero la forma en que escribiste el código consume recursos de CPU del 100% para siempre. En su lugar, debería utilizar un grupo de subprocesos y un planificador como se describe en la respuesta vinculada. Y un 'ServletContextListener' es simplemente el lugar correcto para realizar la inicialización y limpieza global durante el inicio y el apagado de la aplicación. – BalusC

+0

Ok, lo entiendo. Gracias ;) – CeccoCQ

0

ha anulado el método service que es responsable de delegar la llamada a doGet o doPost. see this for more details
También deshaga las llamadas a super.doxxx (..) de cada método. No anule el método service y debería ver "Funciona" desde doGet.

Cuestiones relacionadas