2012-06-12 12 views
8

Tengo un método simple (que se ejecuta en Tomcat 6.0.35) que se ve así:Spring MVC usando @RequestParam con RequestMethod.DELETE en Tomcat 6.0.35

@RequestMapping(value = "/bla/d", method = RequestMethod.DELETE) 
@ResponseStatus(HttpStatus.NO_CONTENT) 
public void d(@RequestParam String d){ 
    //logic here 
} 

cuando envío una solicitud DELETE con el post como los parámetros (d = gggg en el cuerpo) recibo una 400 Solicitud incorrecta. Pero si lo cambio a

@RequestMapping(value = "/bla/d", method = RequestMethod.POST) 
@ResponseStatus(HttpStatus.NO_CONTENT) 
public void d(@RequestParam String d){ 
    //logic here 
} 

Funciona perfectamente. que estaba usando un Firefox Add-on para probarlo (y Python y RestTemplate de primavera con mismo resultado) así es como el aspecto solicitud con el poste (a es un método de hacer frente pegada nombrado con el parámetro a):

POST /bla/a HTTP/1.1 
Host: ~~~~:8080 
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20100101 Firefox/13.0 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
Accept-Encoding: gzip, deflate 
Connection: keep-alive 
Content-Type: application/x-www-form-urlencoded; charset=UTF-8 
Content-Length: 7 
Pragma: no-cache 
Cache-Control: no-cache 
a=asdas 

HTTP/1.1 204 No Content 
Server: Apache-Coyote/1.1 
Date: Tue, 12 Jun 2012 09:29:46 GMT 

y eliminar el siguiente aspecto:

DELETE /bla/d HTTP/1.1 
Host: ~~~~~:8080 
User-Agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:13.0) Gecko/20100101 Firefox/13.0 
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 
Accept-Encoding: gzip, deflate 
Connection: keep-alive 
Content-Type: application/x-www-form-urlencoded; charset=UTF-8 
Content-Length: 7 
d=asdas 

HTTP/1.1 400 Bad Request 
Server: Apache-Coyote/1.1 
Content-Type: text/html;charset=utf-8 
Content-Length: 971 
Date: Tue, 12 Jun 2012 09:30:04 GMT 
Connection: close 

Por favor, ayúdame, puede ser que falte algo estúpido, pero yo no puedo verlo. Mi problema original era enviar una matriz a través de un cuerpo similar a un post con la solicitud DELETE, pero parece que algo más básico es incorrecto.

Respuesta

13

Bien después de investigar y depurar me enteré de que Spring's ServletWebREquest llama getParameterValues ​​of org.apache.catalina.connector.RequestFacade.getParameterValues ​​que invoca getParameterValues ​​en el que he encontrado la siguiente línea (Request.java 2599 -2600):

if (!getMethod().equalsIgnoreCase("POST")) 
return; 

que mata a cualquier intento de enviar parámetros POST-como con DELETE que significa Tomcat es activamente restringe este caso de uso a pesar de que el RFC does not restrict such usage (aunque sí dice que algunas implementaciones existentes pueden rechazar tales solicitudes, Tomcat simplemente arroja sus parámetros de distancia). Lo que trae uno que está usando Spring y Tomcat y tratando de enviar una solicitud DELETE con parámetros a soluciones feas como obtener todo el cuerpo de la solicitud con @RequestBody y extraerlo manualmente lo que hace que su método supuestamente inocente solo quiera borrar algo consciente de algunos Mapa que contiene el cuerpo de la solicitud.

@fmucar

0

que estaba teniendo un problema similar y la resolución que encontré fue la de añadir los campos en la cadena de consulta. Todavía me gustaría saber las razones por las cuales un cuerpo de formulario sería excluido de esta manera, pero por ahora esto es una solución.

Así que, para su ejemplo, significaría agregar ? A = asdas al host: ~~~~~: 8080 URL.

Estoy usando spring-webmvc: 3.2.4.RELEASE así que no estoy seguro de si esto funcionará en su versión o no.

0

Esta es una publicación bastante antigua, pero en caso de que alguien más esté buscando cómo habilitar @RequestParam en los métodos DELETE, esto es lo que hice en tomcat 8.5.4.

@Value("${server.parseBodyMethods}") 
private String parseBodyMethods; 

@Bean 
public TomcatEmbeddedServletContainerFactory containerFactory() { 
    return new TomcatEmbeddedServletContainerFactory() { 
     protected void customizeConnector(Connector connector) { 
      super.customizeConnector(connector); 
      connector.setParseBodyMethods(parseBodyMethods); 
     } 
    }; 
} 

Conecta 'POST, DELETE' a ese personalizador, y los parámetros de tu solicitud de eliminación deberían comenzar a funcionar.

Encontré parseBodyMethods en org.apache.catalina.connector.Conector, y aquí está la documentación de Tomcat:

Esto es útil en aplicaciones RESTful que desean soportar la semántica de estilo POST para solicitudes PUT. Tenga en cuenta que cualquier configuración que no sea POST hace que Tomcat se comporte de una manera que va en contra de la intención de la especificación del servlet. El método HTTP TRACE está específicamente prohibido aquí de acuerdo con la especificación HTTP. El valor predeterminado es POST (Source)

Cuestiones relacionadas