Я понял проблему. В случае, если кто-то сталкивается с подобной проблемой, первым делом нужно проверить, какие фильтры в цепочке пытаются обернуть / реконструировать запрос (содержащий входной поток). Если вы знаете точный фильтр, вы можете отключить его
@Bean
public FilterRegistrationBean registration(PreAuthenticationFilter filter) {
FilterRegistrationBean registration = new FilterRegistrationBean(filter);
registration.setEnabled(false);
return registration;
}
Или вы можете проверить, отключив их все
public class DefaultFiltersBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory bf)
throws BeansException {
DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory)bf;
Arrays.stream(beanFactory.getBeanNamesForType(javax.servlet.Filter.class))
.forEach(
name -> {
BeanDefinition definition =
BeanDefinitionBuilder.genericBeanDefinition(FilterRegistrationBean.class)
.setScope(BeanDefinition.SCOPE_SINGLETON)
.addConstructorArgReference(name)
.addConstructorArgValue(new ServletRegistrationBean[] {})
.addPropertyValue("enabled", false)
.getBeanDefinition();
beanFactory.registerBeanDefinition(name + "FilterRegistrationBean", definition);
});
}
}
В моем случае пользовательский фильтр безопасности разворачивал запрос и восстанавливал входной поток, а лишь частично восстанавливал входной поток и, следовательно, ошибку - MalformedStream.
Я пришел к этому, попробовав эти варианты
- Отключение всей безопасности
security:
basic:
enabled: false
management:
security:
enabled: false
- Удаление автоматически настроенных пружин по умолчанию
spring:
autoconfigure:
exclude: org.springframework.boot.autoconfigure.security.SecurityAutoConfiguration
Однажды я понял, что проблема в безопасности. Я отключил защиту только для POST с inputtream, и inputtream идет невредимым.
@Override public void configure(WebSecurity web) throws Exception {
web.ignoring()
.requestMatchers(ignoreNonJsonMediaTypes())
.and()
.ignoring()
.antMatchers(HttpMethod.POST);
super.configure(web);
}
private MediaTypeRequestMatcher ignoreNonJsonMediaTypes() {
MediaTypeRequestMatcher
matcher =
new MediaTypeRequestMatcher(new HeaderContentNegotiationStrategy(), MediaType.APPLICATION_JSON);
matcher.setIgnoredMediaTypes(Collections.singleton(MediaType.ALL));
return matcher;
}