2017-09-07 14 views
1

Mon application Spring retourne toujours un HTTP 406 - Non acceptable si j'essaie de GET une image de mon RestController, si je n'utilise pas l'extension correcte ou Accept-Header.Conflit avec Accept */* En-tête lors de l'utilisation par défaut ContentType et @ RequestMethod.produces

  • curl http://localhost/images/42 -> 406
  • curl http://localhost/images/42.png -> 200
  • curl http://localhost/images/42 -H 'Accept: image/png' -> 200

Voici mon code contrôleur:

@RequestMapping(path = "/images/{id}", produces = MediaType.IMAGE_PNG_VALUE) 
public void getImage(@PathVariable("id") long id, HttpServletResponse response) throws IOException { 
    [...] 
} 

ressort AFAICT reprend le contenu par défaut -type (JSON) si aucun n'est incompatible avec le résultat de la méthamphétamine od et montre ainsi le 406.

public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { 
    configurer.defaultContentType(MediaType.APPLICATION_JSON) 
      .favorParameter(true); 
} 

Il n'y a pas 406 si je retire le ContentType par défaut, mais ensuite mes autres méthodes commencent à produire XML/Plaine-texte/HTML/stuff (arbitrairement), si je laisse de côté Accept -Header/extension de fichier. (Selon l'ordre des méthodes dans le contrôleur)

Il existe certaines applications héritées qui ne définissent pas les en-têtes et s'appuient sur JSON, ce qui n'est pas une option.


TLDR: Comment puis-je dire du printemps qu'il ne doit utiliser le type de contenu par défaut si elle est compatible avec la méthode du contrôleur que j'ai demandé?

Répondre

1

Modifiez la méthode configureContentNegotiation pour inclure une solution de repli après la valeur par défaut.

ContentNegotiationConfigurer#defaultContentTypeStrategy(ContentNegotiationStrategy) ContentNegotiationStrategy

@Override 
public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { 
    final List<MediaType> defaultMediaTypes = ImmutableList.of(MediaType.APPLICATION_JSON, MediaType.ALL); 
    // First try the default, if the method produces (@RequestMapping#produces) something else use any. 
    configurer.defaultContentTypeStrategy(request -> defaultMediaTypes) 
      .favorParameter(true); 
} 
+1

Oh oui, vous avez raison, je ne voyais pas d'autre méthode. Je souhaite que ce soit le comportement par défaut au printemps. Je vais ouvrir un PR sur le printemps pour cette amélioration, si j'ai le temps. –