如何将Spring Pageable响应中的content字段修改为data?
问题描述
我的控制器代码如下:
@GetMapping("/report-authors") @ResponseBody public Page<MyObject> getSth(){ ... }
当前返回的JSON结构为:
{ "content": [ <MyObject> ], "pageable": { ... }, "last": false, "total_pages": 163, "total_elements": 3246, "size": 20, "number": 0, "sort": { "empty": false, "sorted": true, "unsorted": false }, "number_of_elements": 20, "first": true, "empty": false }
需要将响应中的content字段名称修改为data,期望得到的JSON结构如下:
{ "data": [ <MyObject> ], "pageable": { ... }, "last": false, "total_pages": 163, "total_elements": 3246, "size": 20, "number": 0, "sort": { "empty": false, "sorted": true, "unsorted": false }, "number_of_elements": 20, "first": true, "empty": false }
解决方案
下面提供三种可行的实现方式,根据你的场景选择即可:
方式一:使用Jackson Mixin扩展Page类(推荐)
无需修改原有业务代码,通过Jackson的Mixin机制重写content字段的序列化名称:
- 创建Page的Mixin抽象类:
import com.fasterxml.jackson.annotation.JsonProperty; import org.springframework.data.domain.Page; import java.util.List; public abstract class PageMixin<T> { @JsonProperty("data") abstract List<T> getContent(); // 保留其他分页字段的原有序列化名称 @JsonProperty("total_pages") abstract int getTotalPages(); @JsonProperty("total_elements") abstract long getTotalElements(); @JsonProperty("number_of_elements") abstract int getNumberOfElements(); }
- 在Jackson配置类中注册Mixin:
import com.fasterxml.jackson.databind.ObjectMapper; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.domain.Page; @Configuration public class JacksonConfig { @Bean public ObjectMapper objectMapper() { ObjectMapper mapper = new ObjectMapper(); mapper.addMixIn(Page.class, PageMixin.class); return mapper; } }
方式二:自定义分页DTO包装结果
通过创建自定义分页DTO类,将Spring Data的Page对象转换为DTO后返回:
- 定义分页DTO类:
import lombok.Data; import org.springframework.data.domain.Page; import java.util.List; @Data public class PageDTO<T> { private List<T> data; private Object pageable; private boolean last; private int total_pages; private long total_elements; private int size; private int number; private Object sort; private int number_of_elements; private boolean first; private boolean empty; // 静态方法实现Page到DTO的转换 public static <T> PageDTO<T> fromPage(Page<T> page) { PageDTO<T> dto = new PageDTO<>(); dto.setData(page.getContent()); dto.setPageable(page.getPageable()); dto.setLast(page.isLast()); dto.setTotal_pages(page.getTotalPages()); dto.setTotal_elements(page.getTotalElements()); dto.setSize(page.getSize()); dto.setNumber(page.getNumber()); dto.setSort(page.getSort()); dto.setNumber_of_elements(page.getNumberOfElements()); dto.setFirst(page.isFirst()); dto.setEmpty(page.isEmpty()); return dto; } }
- 修改控制器方法的返回值:
@GetMapping("/report-authors") @ResponseBody public PageDTO<MyObject> getSth(){ Page<MyObject> pageResult = ...; // 原有分页查询逻辑 return PageDTO.fromPage(pageResult); }
方式三:自定义Jackson序列化器
编写自定义序列化器,手动控制Page对象的JSON输出格式:
- 实现自定义序列化器:
import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.databind.JsonSerializer; import com.fasterxml.jackson.databind.SerializerProvider; import org.springframework.data.domain.Page; import java.io.IOException; public class CustomPageSerializer extends JsonSerializer<Page<?>> { @Override public void serialize(Page<?> page, JsonGenerator gen, SerializerProvider serializers) throws IOException { gen.writeStartObject(); // 将content替换为data gen.writeObjectField("data", page.getContent()); // 写入其他分页字段 gen.writeObjectField("pageable", page.getPageable()); gen.writeBooleanField("last", page.isLast()); gen.writeNumberField("total_pages", page.getTotalPages()); gen.writeNumberField("total_elements", page.getTotalElements()); gen.writeNumberField("size", page.getSize()); gen.writeNumberField("number", page.getNumber()); gen.writeObjectField("sort", page.getSort()); gen.writeNumberField("number_of_elements", page.getNumberOfElements()); gen.writeBooleanField("first", page.isFirst()); gen.writeBooleanField("empty", page.isEmpty()); gen.writeEndObject(); } }
- 注册序列化器到Jackson配置:
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.domain.Page; @Configuration public class JacksonConfig { @Bean public ObjectMapper objectMapper() { ObjectMapper mapper = new ObjectMapper(); SimpleModule module = new SimpleModule(); module.addSerializer(Page.class, new CustomPageSerializer()); mapper.registerModule(module); return mapper; } }
内容的提问来源于stack exchange,提问作者Maxwell Cheng
相关产品推荐
相关产品推荐

