Spring Boot集成Protobuf报错:不支持application/x-protobuf类型
解决Spring Boot 2.6.9 Protobuf接口Content-Type不支持问题
问题根源
Spring自带的ProtobufHttpMessageConverter默认仅注册了application/x-protobuf媒体类型,而Python端发送的请求头是application/x-protobuf;charset=UTF-8,两者不匹配导致转换器无法识别请求内容,进而抛出不支持的媒体类型异常。
解决方案
方案1:调整ProtobufHttpMessageConverter的支持媒体类型
在配置ProtobufHttpMessageConverter Bean时,主动添加带charset后缀的媒体类型,确保转换器能匹配Python端的请求头:
@Configuration public class WebConfig implements WebMvcConfigurer { @Bean public ProtobufHttpMessageConverter protobufHttpMessageConverter() { ProtobufHttpMessageConverter converter = new ProtobufHttpMessageConverter(); // 添加支持带UTF-8 charset的application/x-protobuf MediaType charsetMediaType = new MediaType("application", "x-protobuf", StandardCharsets.UTF_8); converter.setSupportedMediaTypes(Arrays.asList(charsetMediaType, ProtobufHttpMessageConverter.PROTOBUF)); return converter; } // 注册转换器到Spring MVC的消息转换器列表,确保优先级 @Override public void configureMessageConverters(List<HttpMessageConverter<?>> converters) { converters.add(protobufHttpMessageConverter()); } }
方案2:修改Python端请求头
如果允许调整Python代码,直接将Content-Type和Accept头改为不带charset后缀的application/x-protobuf:
import requests from your_proto_module import ReportCollection # 构造并填充Protobuf数据 report_collection = ReportCollection() # ... 填充业务数据 response = requests.post( "http://your-service-domain/reports/process", data=report_collection.SerializeToString(), headers={ "Content-Type": "application/x-protobuf", "Accept": "application/x-protobuf" } )
方案3:自定义媒体类型匹配规则(进阶)
如果需要兼容更多application/x-protobuf的变种格式,可以配置Spring忽略媒体类型中的charset参数:
@Configuration public class WebConfig implements WebMvcConfigurer { @Override public void configureContentNegotiation(ContentNegotiationConfigurer configurer) { configurer.mediaType("protobuf", MediaType.parseMediaType("application/x-protobuf")) .ignoreAcceptHeader(false) .defaultContentType(MediaType.parseMediaType("application/x-protobuf")); } @Bean public ProtobufHttpMessageConverter protobufHttpMessageConverter() { ProtobufHttpMessageConverter converter = new ProtobufHttpMessageConverter(); // 让转换器接受所有application/x-protobuf相关的媒体类型(包括带charset的) converter.setSupportedMediaTypes(Collections.singletonList(MediaType.parseMediaType("application/x-protobuf"))); return converter; } }
验证步骤
- 启动Spring Boot应用,查看日志确认
ProtobufHttpMessageConverter已被加载 - 用curl模拟请求测试:
curl -X POST http://your-service-domain/reports/process \ -H "Content-Type: application/x-protobuf;charset=UTF-8" \ -H "Accept: application/x-protobuf" \ --data-binary @your-protobuf-data.bin
内容的提问来源于stack exchange,提问作者Saran
相关产品推荐
相关产品推荐

