MVC-принимает JSON, когда тип контента является пользовательским (не application/json)
Я пытаюсь реализовать заголовок Content-Security-Policy-Report-Only для моего веб-сайта.
Для этого мне нужен контроллер, который будет принимать пост-запрос браузеров - который будет отправлять данные о нарушении в виде JSON. Этот запрос, однако, похоже, указывает тип контента как application/csp-report
вместо application/json
(Примечание сбоку: Какого черта??).
Это, по-видимому, заставляет Spring отклонять запрос - похоже, что использование @RequestBody
заставляет spring принимать только те запросы, которые типа содержания "application/json"
.
Даже когда я специально устанавливаю значение consumes
аннотации @RequestMapping
в application/csp-report
, он все равно не принимает запрос.
Я зашел так далеко, что использовал фильтр для обертывания запроса с помощью HttpServletRequestWrapper
, что, по - видимому, является обычным способом изменения поведения запроса.
Я переписал все эти методы: getContentType()
, getHeader(String)
, getHeaders(String)
вернуть "application/json".
Но запрос все равно не проходит.
- чего мне здесь не хватает?
- Есть ли любые лучшие решения для этого, что не требуется ли от меня колдовать с просьбой?
- я бы даже не стал разум разбирает JSON вручную, могу ли я как-то принять его как простой Вместо веревки?
2 ответа:
Согласно документации по
@RequestBody
аннотации,Тело запроса передается через HttpMessageConverter для разрешения аргумента метода в зависимости от типа содержимого запроса
Это означает, что Spring Framework определяет специализированный API для определения того, как определенные типы носителей преобразуются в определенные типы Java при использовании в качестве параметров для конечных точек REST.
Вот довольно хорошая статья, демонстрирующая эти способности.
Существует большое количество встроенных преобразователей Spring, которые вы можете просто настроить и использовать, если ваш формат мультимедиа может быть сопоставлен с их соответствующими форматами мультимедиа. Специально для вашего случая вам стоит посмотреть на один из конвертеров, доступных в spring.конвертер.JSON пакет. В простейшем случае заставить его работать должно быть так же просто, как:
HttpMessageConverter converter = new <JsonConverterOfYourChoice>(JsonMapper); converter.getSupportedMediaTypes().add(new MediaType("application", "csp-report"));
А затем регистрируем такой преобразователь в конфигурацию пружины, как это делаете вы.
Другие доступные типы конвертеров включают:
- StringHttpMessageConverter
- ObjectToStringHttpMessageConverter (если вы уже настроили Spring ConversionService для чтения нужных типов из строки)
- ByteArrayHttpMessageConverter
- FormHttpMessageConverter
- различные XML-конвертеры, живущие в spring.конвертер.xml пакет
- AllEncompassingFormHttpMessageConverter (конвертер, построенный поверх преобразователя формы и способен обрабатывать XML и JSON, а также)
- Protobuf HttpMessageConverter
- Atom/RSS конвертеры сообщений канала.
Наконец, если ни одно из вышеперечисленных условий не подходит для вас, вы можете создать и зарегистрировать собственную реализацию HttpMessageConverter.
Построение ответа М. Прохорова в полный фрагмент, этот код работал для меня, чтобы добавить
application/csp-report
в качестве конвертера сообщений JSON (используя Jackson) в Spring Boot:@Bean public WebMvcConfigurer webMvcConfigurer() { return new WebMvcConfigurerAdapter() { @Override public void extendMessageConverters(List<HttpMessageConverter<?>> converters) { super.extendMessageConverters(converters); final List<MediaType> cspReportMediaTypes = Collections.singletonList(new MediaType("application", "csp-report")); final HttpMessageConverter<Object> cspReportConverter = new MappingJackson2HttpMessageConverter() { @Override public List<MediaType> getSupportedMediaTypes() { return cspReportMediaTypes; } }; converters.add(cspReportConverter); } }; }