Spring Boot下Jackson反序列化Spring Page对象报错如何解决
解决方案
总共3种常用可行方案,可根据你的业务场景选择:
方案1:自定义Jackson反序列化器并全局注册
这是最常用的无侵入方案,直接适配Spring默认的PageImpl结构:
- 先编写自定义反序列化类:
public class PageImplJacksonDeserializer<T> extends StdDeserializer<PageImpl<T>> { protected PageImplJacksonDeserializer() { super(PageImpl.class); } @Override public PageImpl<T> deserialize(JsonParser p, DeserializationContext ctxt) throws IOException { ObjectMapper mapper = (ObjectMapper) p.getCodec(); JsonNode rootNode = mapper.readTree(p); // 读取PageImpl序列化后的默认字段 List<T> content = mapper.readValue(rootNode.get("content").traverse(mapper), new TypeReference<List<T>>() {}); int page = rootNode.get("number").asInt(); int size = rootNode.get("size").asInt(); long total = rootNode.get("totalElements").asLong(); PageRequest pageRequest = PageRequest.of(page, size); return new PageImpl<>(content, pageRequest, total); } }
- 全局注册到Jackson的ObjectMapper中,Spring Boot项目直接在配置类中添加即可:
@Configuration public class JacksonConfig { @Bean public ObjectMapper objectMapper() { ObjectMapper objectMapper = new ObjectMapper(); SimpleModule module = new SimpleModule(); module.addDeserializer(PageImpl.class, new PageImplJacksonDeserializer<>()); // 支持泛型类型擦除场景的适配 objectMapper.registerModule(module); // 可选配置:忽略未知属性,避免字段不匹配报错 objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); return objectMapper; } }
- 反序列化时指定类型参考即可:
// 假设返回的分页内容是User对象 Page<User> userPage = objectMapper.readValue(jsonStr, new TypeReference<PageImpl<User>>() {});
方案2:自定义分页接收DTO
如果不想修改全局Jackson配置,可自己定义一个和Page结构完全一致的普通DTO承接反序列化结果,后续需要时再转为Page对象:
@Data public class PageDTO<T> { private List<T> content; private int number; private int size; private long totalElements; private int totalPages; // 其他你用到的Page字段按需添加 public Page<T> toPage() { return new PageImpl<>(content, PageRequest.of(number, size), totalElements); } }
反序列化时直接用该DTO接收即可:
PageDTO<User> pageDTO = objectMapper.readValue(jsonStr, new TypeReference<PageDTO<User>>() {}); Page<User> userPage = pageDTO.toPage();
方案3:使用Spring Data的Jackson模块(Spring Boot 2.2+ 支持)
Spring Data自带了SpringDataJacksonModules,直接注入即可自动适配Page反序列化,无需自己写反序列化器:
@Configuration public class JacksonConfig { @Bean public ObjectMapper objectMapper(SpringDataJacksonModules modules) { ObjectMapper objectMapper = new ObjectMapper(); objectMapper.registerModules(modules); objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); return objectMapper; } }
如果是用RestTemplate或者WebClient调用接口,直接注入配置好的ObjectMapper到对应的消息转换器中即可生效。
注意:如果你的API返回的Page对象做过自定义字段扩展,需要对应调整反序列化逻辑的字段映射关系。
内容的提问来源于stack exchange,提问作者Véoth
相关产品推荐
相关产品推荐

