2012-06-12 13 views
8

Ho un metodo semplice (in esecuzione su Tomcat 6.0.35) che assomiglia così:Spring MVC utilizzando @RequestParam con RequestMethod.DELETE su Tomcat 6.0.35

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

quando invio una richiesta di eliminazione con il post come i parametri (d = gggg nel corpo) ottengo 400 richieste errate. Ma se cambio a

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

Funziona perfettamente. Io sto usando un add-on Firefox per provarlo (e pitone e RestTemplate di primavera con lo stesso risultato) ecco come il look richiesta con POST (una è un metodo di far fronte incollato nominato con il parametro 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 

E cancella sembra:

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 

Per favore aiutami, potrei mancarmi qualcosa di stupido ma non riesco proprio a vederlo. Il mio problema originale era inviare un array tramite un corpo post-like con la richiesta DELETE ma sembra che qualcosa di più semplice sia sbagliato.

risposta

13

Bene dopo aver fatto qualche ricerca e debug, ho scoperto che Spring's ServletWebREquest chiama getParameterValues ​​di org.apache.catalina.connector.RequestFacade.getParameterValues ​​che chiama getParameterValues ​​in cui ho trovato la seguente riga (Request.java 2599 -2600):

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

che uccide ogni tentativo di inviare i parametri POST-like con DELETE che significa Tomcat è attivamente limita questo caso d'uso anche se la RFC does not restrict such usage (anche se dice che alcune implementazioni esistenti possono rifiutare tale richieste, Tomcat butta via solo i suoi parametri). Ciò che porta uno usa Spring e Tomcat e prova a inviare richieste DELETE con parametri a soluzioni orribili come ottenere tutto il corpo della richiesta con @RequestBody ed estrarlo manualmente, il che rende il tuo metodo apparentemente innocente che vuole solo cancellare qualcosa di Mappa che contiene il corpo della richiesta.

@fmucar

0

stavo avendo un problema simile e la risoluzione che ho trovato è stato quello di aggiungere i campi nella stringa di query. Mi piacerebbe ancora sapere quali sono i motivi per cui un corpo di form dovrebbe essere escluso in questo modo, ma per ora questo è un work-around.

Quindi per il tuo esempio significherebbe aggiungere ? A = asdas all'host: ~~~~~: 8080 URL.

Sto usando spring-webmvc: 3.2.4.RELEASE quindi non sono sicuro se questo funzionerà nella versione o no.

0

Questo è un post piuttosto vecchio, ma nel caso in cui qualcun altro stia cercando come abilitare @RequestParam sui metodi DELETE, ecco cosa ho fatto su 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); 
     } 
    }; 
} 

plug in 'POST, DELETE' a quel customizer, nonché i propri parametri richiesta di eliminazione dovrebbe iniziare a lavorare.

Ho trovato parseBodyMethods in org.apache.catalina.connector.Connector, ed ecco la documentazione di Tomcat su di esso:

Questo è utile nelle applicazioni RESTful che vogliono supportare la semantica in stile POST per le richieste PUT. Si noti che qualsiasi impostazione diversa dal POST induce Tomcat a comportarsi in modo contrario all'intento delle specifiche del servlet. Il metodo HTTP TRACE è specificamente proibito qui in conformità con le specifiche HTTP. L'impostazione predefinita è POST (Source)

Problemi correlati