Весна необъяснимо вызывает исключение HttpMediaTypeNotAcceptableException

#spring #spring-mvc #content-negotiation

#весна #весна-mvc #согласование контента

Вопрос:

У меня есть приложение Spring, настроенное на использование параметра GET для согласования содержимого. Код-это Kotlin, но он будет работать так же на Java.

Конфигурация:

 override fun configureContentNegotiation(configurer: ContentNegotiationConfigurer) {  configurer.favorParameter(true)  .parameterName("format")  .ignoreAcceptHeader(false)  .defaultContentType(MediaType.APPLICATION_JSON)  .mediaType("text/plain", MediaType.TEXT_PLAIN)  .mediaType("application/json", MediaType.APPLICATION_JSON)  .mediaType("application/rdf xml", MediaType("application", "rdf xml"))  }  

И следующие методы контроллера:

 @GetMapping("/test", produces=["text/plain"]) fun testText() : String {  return "Hello" }  @GetMapping("/test", produces=["application/json"]) fun testJson() : Maplt;String, Stringgt; {  return mapOf("hello" to "world") }  @GetMapping("/test", produces=["application/rdf xml"]) fun testRdf(response: HttpServletResponse) {  // dummy response, to demonstrate using output stream.  response.setContentType("application/rdf xml")  response.outputStream.write("dummy data".toByteArray())  response.outputStream.close() }  

testRdf возвращает void и использует выходной поток для отправки данных тела обратно.

Следующее работает просто отлично:

  • http://localhost:8080/test?format=text/plain дает мне простой текст
  • http://localhost:8080/test?format=application/json дает мне JSON

Но http://localhost:8080/test?format=application/rdf xml дает мне HTTP 406, и в журналах говорится

 org.apache.tomcat.util.http.Parameters : Start processing with input [format=application/rdf xml] o.s.web.servlet.DispatcherServlet : GET "/test?format=application/rdf xml", parameters={masked} .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.HttpMediaTypeNotAcceptableException: Could not find acceptable representation] o.s.web.servlet.DispatcherServlet : Completed 406 NOT_ACCEPTABLE  

Отладчик показывает, что он даже не вызывает мою функцию.

(Чтобы доказать, что testRdf обработчик делает то, что ожидается, я сделал путь уникальным и удалил produces аннотацию — она отлично работает вне согласования содержимого и возвращает тело, как и ожидалось.)

Насколько я могу судить, я указал, что мой метод является правильным обработчиком для этого типа контента, и я правильно зарегистрировал тип контента.

Почему Spring не считает, что мой обработчик удовлетворяет запросу согласования содержимого?

Ответ №1:

Я нашел ответ. Символы параметров, которые должны были быть закодированы в URL, поэтому это работает нормально:

 http://localhost:8080/test?format=application/rdf+xml