Ho un'applicazione Spring MVC che riceve una richiesta HTTP da un sistema esterno sotto forma di una stringa JSON e la sua risposta viene restituita allo stesso modo di una stringa JSON. Il mio controller è annotato correttamente con @RequestBody
e @ResponseBody
e ho test di integrazione che effettivamente inviano richieste per verificare che tutto funzioni come previsto.Spring MVC: @RequestBody quando non è specificato alcun tipo di contenuto
Tuttavia, quando sono andato a testare la mia applicazione contro il sistema esterno effettivo che lo utilizzerà, ho scoperto che le richieste in arrivo non specificavano un tipo di contenuto! Questo confonde completamente primavera e risultati nei seguenti tipi di errori:
DEBUG [] 2014-04-17 13:33:13,471 AbstractHandlerExceptionResolver.java:132 resolveException - Resolving exception from handler [[email protected]]: org.springframework.web.HttpMediaTypeNotSupportedException: Cannot extract parameter (ValidationRequest request): no Content-Type found
Quindi, c'è un modo per forzare primavera per instradare tale richiesta tramite il MappingJacksonHttpMessageConverter
, sia in qualche modo costringendo Primavera di utilizzare una catena gestore personalizzato o modificando la richiesta in arrivo per impostare esplicitamente un tipo di contenuto?
Ho provato un paio di cose:
- Estendere
MappingJacksonHttpMessageConverter
modo che i suoicanRead()
ecanWrite()
metodi restituiscono sempre vero. Sfortunatamente, Spring non arriva nemmeno al punto di guardare i convertitori di messaggi prima del salvataggio a causa della mancanza di tipo di contenuto. - Utilizzo di intercettatori o filtri Servlet per impostare manualmente il tipo di contenuto. Sfortunatamente, non riesco a vedere un modo per entrambi questi meccanismi di apportare effettivamente una modifica alla richiesta in arrivo oltre a impostare nuovi attributi.
Tutte le idee sono apprezzate.
per affrontare i commenti qui sotto, il mio @RequestMapping
assomiglia:
@RequestMapping(value="/{service}")
public @ResponseBody MyResponseObject(@PathVariable String service, @RequestBody MyRequestObject request) {
Quindi qui non c'è niente che specifica JSON, ma senza un tipo di contenuto primavera non sembra prendere anche una pugnalata a edificio la mia richiesta oggetto dalla richiesta in entrata (che ha senso, in quanto non ha abbastanza informazioni per determinare come farlo).
E come per il commento di @ geoand che chiede "perché non si può aggiungere l'intestazione http del tipo di contenuto in un filtro servlet o Spring Interceptor", la risposta è "perché sono stupido e ho dimenticato come funzionano i filtri servlet". Questo è l'approccio che alla fine ho usato per risolvere il problema, che aggiungerò imminentemente come risposta.
Se i normali filtri servlet non funzionano, hai provato il RequestInterceptorFilter di Spring? Dovrai intercettare la richiesta e scrivere una nuova risposta che verrà inoltrata alla primavera. –
Aggiungi il tuo @RequestMapping Code –
Hai esplicitamente dichiarato nella richiesta mapping che puoi accettare solo json? Perché non è possibile aggiungere l'intestazione http del tipo di contenuto in un filtro servlet o in Spring Interceptor? – geoand