TL; DR
Почему и как пружина перезаписывает ContentType в заголовке?
Существует конфигурация пружины по умолчанию, основанная на 3 стратегиях, которые выбирают тип содержимого подлежит возврату. Конфигурация может быть изменена.
Настройка всех ответов заголовка типа содержимого от всех контроллеров
Существует два способа настройки конфигурации согласования заголовка типа содержимого для всех ответов: XML, а другой - через конфигурацию, управляемую аннотациями.
Настройка значения заголовка типа содержимого для определенных URL-адресов
В той же конфигурации существует способ внедрения индивидуальной стратегии для выбора URL-адресов должно быть затронуто правило изменения заголовка типа содержимого.
При загрузке Spring
К счастью, при загрузке Spring добавление атрибута production в аннотацию @RequestMapping контроллера, а также изменение свойства было бы достаточным для получения желаемого поведения:
- @ RequestMapping (value = "/live/timeshift.m3u8", method = RequestMethod.GET, производит = "application / vnd.apple.mpegurl")
- Свойство -> spring .http.encoding.enabled установлено значение true
Длинный ответ
Почему и как Spring перезаписывает ContentType в заголовке?
В Spring MVC есть три варианта определения типа носителя запроса:
- суффиксы (расширения) URL-адреса в запросе (например, .xml /.json)
- Параметр URL в запросе (например,? Format = json)
- Заголовок Accept в запросе, выполненном для метода вашего контроллера
Именно в этом порядке Spring согласование ответ заголовка типа содержимого и формат ответа тела, и если не Если из них включены, мы можем указать откат к типу контента по умолчанию.
Настройка всех ответов заголовков типа контента от всех контроллеров
Поэтому для настройки этого поведения мы должны предоставить откатить тип содержимого по умолчанию и отключить три описанные выше стратегии. Есть два подхода к его выполнению, используя конфигурацию XML или конфигурацию аннотации:
@Configuration
@EnableWebMvc
public class WebConfig extends WebMvcConfigurerAdapter {
@Override
public void configureContentNegotiation(final ContentNegotiationConfigurer configurer) {
configurer.favorPathExtension(false).
favorParameter(false).
ignoreAcceptHeader(true).
useJaf(false).
defaultContentType("application/vnd.apple.mpegurl");
}
}
или XML конфигурация
<bean id="contentNegotiationManager"
class="org.springframework.web.accept.ContentNegotiationManagerFactoryBean">
<property name="favorPathExtension" value="false" />
<property name="favorParameter" value="false"/>
<property name="ignoreAcceptHeader" value="true" />
<property name="defaultContentType" value="application/vnd.apple.mpegurl"/>
<property name="useJaf" value="false" />
</bean>
Настройка значения заголовка типа содержимого для определенных URL-адреса
Еще одно индивидуальное решение - создать собственную аннотацию @DefaultContentType. Переопределение RequestMappingHandlerMapping # getCustomMethodCondition, которое проверяет наличие annotation@DefaultContentType в методе. Пользовательское условие всегда будет совпадать, но в compareTo оно будет отдавать приоритет методам, имеющим аннотацию, по сравнению с теми, у которых их нет.
Я бы применил вышеуказанное решение, если вам нужно использовать его много раз.
Для разового возникновения вы можете подключить настраиваемый defaultContentTypeStrategy через ContentNegotiationConfigurer, который проверяет указанный c URL и возвращает предпочтительный тип мультимедиа, например:
public class MyCustomContentNegotiationStrategy implements ContentNegotiationStrategy {
@Override
public List<MediaType> resolveMediaTypes (final NativeWebRequest nativeWebRequest)
throws HttpMediaTypeNotAcceptableException {
final List<MediaType> mediaTypes = new ArrayList<>();
final String url =((ServletWebRequest)request).getRequest().getRequestURI().toString();
final String yourUrlpatternString = ".*http://.*";
final Pattern yourUrlPattern = Pattern.compile(patternString);
final Matcher matcher = pattern.matcher(url);
if(matcher.matches()) {
mediaTypes.add("application/vnd.apple.mpegurl");
return mediaTypes;
}
}
Затем добавьте ваша индивидуальная стратегия через конфигурацию:
@EnableWebMvc
@Configuration
public class MyWebConfig extends WebMvcConfigurerAdapter {
@Override
public void configureContentNegotiation (ContentNegotiationConfigurer configurer) {
configurer.defaultContentTypeStrategy(new MyCustomContentNegotiationStrategy());
}
}
При загрузке Spring
Наконец, если вы используете весеннюю загрузку, как предложил @StavShamir, в ответе { ссылка }, есть несколько общих свойств приложения, которые могут быть полезны в этом случае:
# HTTP encoding (HttpEncodingProperties)
# Charset of HTTP requests and responses. Added to the "Content-Type" header if not set explicitly.
spring.http.encoding.charset=UTF-8
# Whether to enable http encoding support.
spring.http.encoding.enabled=true
# Whether to force the encoding to the configured charset on HTTP requests and responses.
spring.http.encoding.force=
# Whether to force the encoding to the configured charset on HTTP requests. Defaults to true when "force" has not been
spring.http.encoding.force-request= specified.
# Whether to force the encoding to the configured charset on HTTP responses.
spring.http.encoding.force-response=
# Locale in which to encode mapping.
spring.http.encoding.mapping=
https://docs.spring.io/spring-boot/docs/current-SNAPSHOT/reference/htmlsingle/#common -application-properties
Именно в этом случае , для свойства spring.http.encoding.enabled установлено значение true, и использование аргумента создает аргумент в аннотации @RequestMapping:
@RequestMapping(value = "/live/timeshift.m3u8", method = RequestMethod.GET, produces = "application/vnd.apple.mpegurl")