如何通过RestTemplate将返回的字符串格式字段解析为对象?
问题描述
调用Web服务返回的JSON中,supplierPayload字段以字符串形式返回,但实际是JSON对象,示例如下:
{ "message": "OK", "code": 1, "supplierPayload": "{\"field01\":\"value01\",\"field02\":\"field02\"}" }
希望通过RestTemplate调用时,直接将该字段解析为SupplierPayload对象,使用代码:
this.restTemplate.getForEntity(url, MyObject.class);
其中MyObject定义为:
public class MyObject { private String message; private int code; private SupplierPayload supplierPayload; // getter和setter }
避免用字符串类型接收后手动处理,省去到处注入ObjectMapper和处理嵌套受检异常的麻烦。
解决方案
方式一:字段级自定义反序列化(推荐单字段场景)
- 编写自定义Jackson反序列化器,实现字符串到
SupplierPayload的转换:
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.ObjectMapper; import java.io.IOException; public class NestedJsonDeserializer extends JsonDeserializer<SupplierPayload> { private static final ObjectMapper objectMapper = new ObjectMapper(); @Override public SupplierPayload deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { // 读取字符串形式的JSON,再反序列化为目标对象 String nestedJson = p.getText(); return objectMapper.readValue(nestedJson, SupplierPayload.class); } }
- 在
MyObject的supplierPayload字段上添加注解,指定使用该反序列化器:
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; public class MyObject { private String message; private int code; @JsonDeserialize(using = NestedJsonDeserializer.class) private SupplierPayload supplierPayload; // getter和setter }
完成后直接调用RestTemplate即可,Jackson会自动处理该字段的转换逻辑。
方式二:全局配置RestTemplate(推荐多场景复用)
如果多个接口或字段需要处理这类嵌套JSON字符串,可全局配置RestTemplate的ObjectMapper:
- 创建自定义Jackson模块,注册反序列化器:
import com.fasterxml.jackson.databind.module.SimpleModule; public class CustomJsonModule extends SimpleModule { public CustomJsonModule() { // 为SupplierPayload类型绑定自定义反序列化器 addDeserializer(SupplierPayload.class, new NestedJsonDeserializer()); } }
- 配置
RestTemplate时,替换其默认的消息转换器,注入自定义模块:
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.client.RestTemplate; public RestTemplate customRestTemplate() { RestTemplate restTemplate = new RestTemplate(); MappingJackson2HttpMessageConverter jsonConverter = new MappingJackson2HttpMessageConverter(); // 注册自定义模块 jsonConverter.getObjectMapper().registerModule(new CustomJsonModule()); // 替换默认的Jackson消息转换器 restTemplate.getMessageConverters().replaceAll(converter -> converter instanceof MappingJackson2HttpMessageConverter ? jsonConverter : converter); return restTemplate; }
后续使用这个自定义的RestTemplate发起请求时,所有SupplierPayload类型的字段都会自动完成字符串到对象的转换。
内容的提问来源于stack exchange,提问作者Philippe Gioseffi
相关产品推荐
相关产品推荐

