Spring WebClient设置带schema URL的Content-Type header报错如何解决?
Spring WebClient设置无引号特殊参数Content-Type方案
问题根因
Spring对Content-Type这类标准HTTP头默认会执行MediaType格式校验,按照RFC规范,媒体类型参数值如果包含:、/这类特殊字符需要用双引号包裹,但对接的第三方接口强制要求不能加引号,因此触发InvalidMediaTypeException异常。
解决方案
核心逻辑是绕过Spring的MediaType校验逻辑,直接写入原生Header字符串,有两种常用实现方式:
1. 单次请求适配方案
如果仅部分请求需要该特殊Content-Type,直接在请求构造时通过httpRequest回调设置原生Header即可:
webClient.post() .uri("/dr/v1/receipts") .attributes(clientRegistrationId(clientRegistrationId)) // 直接操作原生请求对象的Header,绕过MediaType校验 .httpRequest(request -> { request.getHeaders().set("Content-Type", "application/json;profile=https://se.digitalreceipts.net/schemas/json/retail/v1.0"); }) // 原有请求body、响应处理逻辑保持不变 .bodyValue(yourRequestBody) .retrieve() .bodyToMono(YourResponse.class);
2. 全局适配方案
如果所有请求都需要使用该Content-Type,构造WebClient时添加全局过滤器统一设置:
WebClient webClient = WebClient.builder() .filter((request, next) -> { ClientHttpRequest mutatedRequest = new ClientHttpRequestDecorator(request) { @Override public HttpHeaders getHeaders() { HttpHeaders headers = super.getHeaders(); headers.set("Content-Type", "application/json;profile=https://se.digitalreceipts.net/schemas/json/retail/v1.0"); return headers; } }; return next.exchange(mutatedRequest); }) // 其他原有WebClient配置保持不变 .build();
注意事项
- 不要使用
contentType(MediaType)方法设置媒体类型,该方法会强制触发格式校验 - 不要直接调用
header("Content-Type", "xxx")传值,同样会触发Spring内部的MediaType解析校验
内容的提问来源于stack exchange,提问作者Kristoffer S
相关产品推荐
相关产品推荐

