You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过RestTemplate在反序列化前查看API响应内容?

查看RestTemplate反序列化前的API响应

问题场景

你在使用Spring的RestTemplate调用API时遇到了这样的困扰:API文档存在错误,导致DesignatedDto无法正常完成响应反序列化,之前只能联系开发者拿到真实响应才能解决问题。现在想知道有没有无需联系开发者,就能在反序列化前查看原始API响应的方法——而且不能用String::class.java替代DesignatedDto::class.java接收响应,因为会触发如下错误:

org.springframework.web.client.RestClientException: Error while extracting response for type [class java.lang.String] and content type [text/html;charset=UTF-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize instance of java.lang.String out of START_OBJECT token; nested exception is com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of java.lang.String out of START_OBJECT token at [Source: (PushbackInputStream); line: 6, column: 1]

实用解决方案

这里有几个在Spring生态内就能实现的靠谱方法,完全满足你的需求:

1. 用ResponseEntity<byte[]>接收原始响应

这是最直接的方式,字节数组能完整保留响应的原始格式,不会触发任何自动解析:

val response = restTemplate.exchange(url, HttpMethod.POST, requestEntity, ByteArray::class.java)
// 将字节数组转为字符串查看,注意匹配API响应的编码(通常是UTF-8)
val rawResponse = String(response.body!!, Charsets.UTF_8)
println("原始API响应内容:$rawResponse")
// 确认响应无误后,再手动反序列化到目标DTO
val objectMapper = ObjectMapper()
val dto = objectMapper.readValue(rawResponse, DesignatedDto::class.java)

这种方式既拿到了原始响应内容,之后也能正常完成反序列化,完美避开了直接用String接收的解析错误。

2. 开启RestTemplate的DEBUG日志

Spring的RestTemplate支持通过日志打印完整的请求和响应细节,不需要修改业务代码,只需要在日志配置中开启对应包的DEBUG级别:

# 若使用application.properties配置
logging.level.org.springframework.web.client.RestTemplate=DEBUG

开启后,日志会输出完整的响应头、响应体内容,你可以直接从日志里查看原始响应。注意:生产环境请关闭该配置,避免敏感数据泄露。

3. 自定义拦截器拦截响应

如果需要精准控制哪些请求需要查看响应(比如只在调试特定接口时启用),可以写一个自定义拦截器:

class ResponseLoggingInterceptor : ClientHttpRequestInterceptor {
    override fun intercept(request: HttpRequest, body: ByteArray, execution: ClientHttpRequestExecution): ClientHttpResponse {
        val response = execution.execute(request, body)
        // 读取响应体内容并打印
        val responseBody = StreamUtils.copyToString(response.body, Charsets.UTF_8)
        println("拦截到的API响应:$responseBody")
        // 必须重新包装响应体,因为输入流只能读取一次
        return BufferingClientHttpResponseWrapper(response)
    }
}

然后将这个拦截器添加到你的RestTemplate实例中:

restTemplate.interceptors.add(ResponseLoggingInterceptor())

这种方式不会影响正常的反序列化流程,还能灵活控制拦截范围。


内容的提问来源于stack exchange,提问作者Doo Hyun Shin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 15:57:27