#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