使用Spring RestTemplate调用API时遇mark/reset not supported异常求助
解决RestTemplate POST请求的"mark/reset not supported"异常
这个异常的核心原因是:RestTemplate默认使用的消息转换器(比如MappingJackson2HttpMessageConverter)会尝试对请求体的输入流执行mark()/reset()操作,但当前请求流不支持该特性。通常是因为底层HTTP客户端没有对请求体做缓冲处理。
下面提供两种可行的解决方法:
方法一:修改消息转换器,禁用请求体缓存
自定义MappingJackson2HttpMessageConverter,关闭其请求体缓存功能,避免触发mark/reset操作:
@Bean public RestTemplate restTemplate() { RestTemplate restTemplate = new RestTemplate(); // 找到并替换默认的MappingJackson2HttpMessageConverter for (int i = 0; i < restTemplate.getMessageConverters().size(); i++) { if (restTemplate.getMessageConverters().get(i) instanceof MappingJackson2HttpMessageConverter) { MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); converter.setSupportedMediaTypes(Collections.singletonList(MediaType.APPLICATION_JSON)); // 禁用请求体缓存,跳过mark/reset操作 converter.setBuffering(false); restTemplate.getMessageConverters().set(i, converter); break; } } return restTemplate; }
方法二:用BufferingClientHttpRequestFactory包装请求工厂
通过BufferingClientHttpRequestFactory将请求体缓冲到内存中,让流支持mark/reset:
@Bean public RestTemplate restTemplate() { SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory(); // 包装为缓冲请求工厂,把请求体存入内存实现mark/reset支持 BufferingClientHttpRequestFactory bufferingFactory = new BufferingClientHttpRequestFactory(requestFactory); RestTemplate restTemplate = new RestTemplate(bufferingFactory); return restTemplate; }
选择说明
- 方法一更轻量,适合不需要重复读取请求体的场景,直接避免触发不支持的操作;
- 方法二兼容性更强,能适配所有需要
mark/reset的场景,比如某些拦截器需要重复读取请求体的情况。
内容的提问来源于stack exchange,提问作者Hani Bikdeli
相关产品推荐
相关产品推荐

