解析MIME类型"application/json charset=utf-8"及解决Spring InvalidMimeTypeException
MIME类型解析与WebClient调用异常修复
一、"application/json charset=utf-8"的含义
标准的JSON格式MIME类型应该是application/json; charset=utf-8,用分号分隔主类型和字符集参数。但这个写法把分号换成了空格,属于不符合HTTP规范的错误格式:
application/json:明确响应内容是JSON格式的数据charset=utf-8:说明内容采用UTF-8编码
正是这个空格导致Spring的MIME类型解析器无法识别,抛出InvalidMimeTypeException异常。
二、WebClient调用异常的修复方法
因为没法修改第三方服务的响应头,只能在自己的WebClient代码里做兼容处理,有两种实用方案:
方案1:自定义消息转换器,兼容错误格式
直接给Jackson消息转换器添加对这个错误MIME类型的支持,让它能识别这种不规范的Content-Type:
MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); // 同时支持标准格式和错误格式的JSON类型 converter.setSupportedMediaTypes(Arrays.asList( MediaType.APPLICATION_JSON, MimeType.valueOf("application/json charset=utf-8") )); // 构建WebClient时替换默认的消息转换器 WebClient client = WebClient.builder() .clientConnector(new ReactorClientHttpConnector(httpClient)) .exchangeStrategies(ExchangeStrategies.builder() .messageConverters(converters -> converters.add(0, converter)) .build()) .build();
方案2:拦截响应,修正Content-Type再解析
通过WebClient的过滤器拦截响应,把Content-Type里的空格替换成分号,让Spring的解析器能正常处理:
WebClient client = WebClient.builder() .clientConnector(new ReactorClientHttpConnector(httpClient)) .filter((request, next) -> next.exchange(request) .map(response -> { // 获取原始的Content-Type值 String originalContentType = response.headers().header(HttpHeaders.CONTENT_TYPE) .stream().findFirst().orElse(null); if (originalContentType != null && originalContentType.contains("application/json charset=utf-8")) { // 把空格替换成标准的分号分隔符 String fixedContentType = originalContentType.replace(" ", ";"); // 构建新的响应头 HttpHeaders newHeaders = new HttpHeaders(); newHeaders.putAll(response.headers().asHttpHeaders()); newHeaders.set(HttpHeaders.CONTENT_TYPE, fixedContentType); // 返回修正后的响应对象 return ClientResponse.from(response) .headers(headers -> headers.putAll(newHeaders)) .build(); } return response; })) .build();
为啥SoapUI能正常调用?
SoapUI对HTTP头的解析逻辑没有Spring这么严格,它允许Content-Type里用空格代替分号,所以不会触发校验错误。
内容的提问来源于stack exchange,提问作者Abdul
相关产品推荐
相关产品推荐

