Spring RestTemplate中基于type字段的JSON多类型POJO映射方案咨询
解决方案:利用Jackson自定义反序列化器实现动态类型映射
要实现根据type字段把JSON数组元素动态映射到不同的Data实现类,你可以借助Spring Boot默认使用的Jackson框架的自定义反序列化器来搞定。下面是一步步的具体实现:
步骤1:给Data接口标记反序列化注解
先在你的Data接口上添加@JsonDeserialize注解,指定我们要自定义的反序列化器:
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; @JsonDeserialize(using = DataDeserializer.class) public interface Data { }
步骤2:实现自定义的Data反序列化器
创建一个DataDeserializer类,继承Jackson的JsonDeserializer<Data>,在核心的deserialize方法里根据type字段的值判断要实例化哪个具体类:
import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.JsonNode; import java.io.IOException; public class DataDeserializer extends JsonDeserializer<Data> { @Override public Data deserialize(JsonParser parser, DeserializationContext context) throws IOException { JsonNode node = parser.getCodec().readTree(parser); // 读取JSON中的type字段值 String type = node.get("type").asText(); // 根据type选择对应的实现类完成反序列化 return switch (type) { case "type1" -> parser.getCodec().treeToValue(node, Type1.class); case "type2" -> parser.getCodec().treeToValue(node, Type2.class); // 新增类型时直接加case即可,也可以自定义默认处理逻辑 default -> throw new IllegalArgumentException("不支持的数据类型: " + type); }; } }
步骤3:配置RestTemplate(可选)
如果你的RestTemplate是自定义配置的,只需要确保它使用的ObjectMapper能识别我们的注解即可——其实因为我们已经在Data接口上标记了@JsonDeserialize,Jackson会自动加载这个反序列化器,大部分场景下不需要额外配置。如果需要手动配置ObjectMapper,可以参考下面的代码:
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.web.client.RestTemplate; import com.fasterxml.jackson.databind.ObjectMapper; @Configuration public class RestTemplateConfig { @Bean public RestTemplate restTemplate() { RestTemplate restTemplate = new RestTemplate(); MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter(); converter.setObjectMapper(objectMapper()); restTemplate.getMessageConverters().add(converter); return restTemplate; } @Bean public ObjectMapper objectMapper() { ObjectMapper objectMapper = new ObjectMapper(); // 这里无需手动注册反序列化器,注解已经生效,可添加其他Jackson配置 return objectMapper; } }
步骤4:测试调用
现在你可以正常用RestTemplate调用API了,Jackson会自动把JSON数组里的元素映射到对应的Type1或Type2实例:
@Autowired private RestTemplate restTemplate; public void fetchAndProcessData() { String apiUrl = "你的API接口地址"; MyResponse response = restTemplate.getForObject(apiUrl, MyResponse.class); // 遍历data列表,根据实际类型处理逻辑 for (Data data : response.getData()) { if (data instanceof Type1 type1) { System.out.println("Type1的property1值: " + type1.getProperty1()); } else if (data instanceof Type2 type2) { System.out.println("Type2的数组元素: " + type2.getPropArray()); } } }
补充说明
- 后续新增
type类型时,只需要添加对应的实体类,并在反序列化器的switch里加一个case即可 - 可以根据业务需求调整未知
type的处理逻辑,比如返回null或者自定义业务异常 - 如果
type字段在JSON中的层级有变化,只需要调整node.get("type")的路径即可
内容的提问来源于stack exchange,提问作者adesai
相关产品推荐
相关产品推荐

