如何在读取JSON文件的非Repository Spring Boot项目中使用Pageable?
嘿,我完全懂你的处境——用Spring Data JPA的时候加个Pageable就能轻松实现分页,可换成从本地JSON文件读数据就卡壳了对吧?别慌,咱们一步步把这个问题搞定。
为什么会报错?
你遇到的类型不兼容问题很明确:consumer.getJson()返回的是List<JsonNode>,但你试图把它赋值给Page<JsonNode>类型的变量。Spring Data的Page可不是简单的列表,它是一个包含分页元数据(总页数、当前页号、每页数量、总元素数等)的包装类,和普通List完全是两回事。
解决方案:手动将List转换为Page
咱们可以借助Spring Data提供的PageImpl(Page接口的默认实现类)来手动构建分页对象,步骤如下:
1. 在Controller方法中接收分页参数
首先,让你的GET请求方法接收Spring的Pageable参数,Spring会自动解析请求中的page(默认从0开始)、size(默认20)、sort等参数并绑定到这个对象上:
import org.springframework.data.domain.Page; import org.springframework.data.domain.Pageable; import org.springframework.data.domain.PageImpl; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; import com.fasterxml.jackson.databind.JsonNode; import java.util.Collections; import java.util.List; @RestController public class JsonDataController { private final JsonConsumer consumer; // 假设这是你的getJson()所在的类 // 构造注入 public JsonDataController(JsonConsumer consumer) { this.consumer = consumer; } @GetMapping("/paginated-json-data") public Page<JsonNode> getPaginatedJsonData(Pageable pageable) throws IOException { // 这里写分页逻辑 } }
2. 获取完整数据并计算分页边界
先拿到所有JSON数据,然后根据Pageable参数计算当前页的起始和结束索引,注意要处理边界情况(比如请求的页码超过总页数时返回空列表):
// 1. 获取全部JSON数据 List<JsonNode> fullJsonList = consumer.getJson(); int totalElements = fullJsonList.size(); // 2. 计算分页索引 int pageSize = pageable.getPageSize(); int currentPage = pageable.getPageNumber(); int startIndex = currentPage * pageSize; // 处理超出边界的情况:如果起始索引大于等于总元素数,返回空页 if (startIndex >= totalElements) { return new PageImpl<>(Collections.emptyList(), pageable, totalElements); } // 计算结束索引,不能超过总元素数 int endIndex = Math.min(startIndex + pageSize, totalElements);
3. 截取当前页数据并构建Page对象
从完整列表中截取当前页的子集,然后用PageImpl把数据和分页元数据包装起来:
// 3. 截取当前页的内容 List<JsonNode> currentPageContent = fullJsonList.subList(startIndex, endIndex); // 4. 构建Page对象并返回 return new PageImpl<>(currentPageContent, pageable, totalElements);
额外优化:自定义分页默认值与排序
如果需要修改分页参数的默认值(比如默认每页10条数据),可以用@PageableDefault注解:
import org.springframework.data.domain.Pageable; import org.springframework.data.domain.PageableDefault; @GetMapping("/paginated-json-data") public Page<JsonNode> getPaginatedJsonData( @PageableDefault(page = 0, size = 10, sort = "id") Pageable pageable) throws IOException { // 逻辑不变 }
要是需要对JSON数据排序,你可以先对fullJsonList进行排序再分页,比如根据id字段升序:
// 排序示例:根据JsonNode中的"id"字段升序排列 fullJsonList.sort(Comparator.comparing(node -> node.get("id").asLong()));
这样返回的Page<JsonNode>对象就和Spring Data JPA返回的分页结构完全一致,前端可以直接获取分页元数据(比如totalPages、number、size等),完美适配现有逻辑!
内容的提问来源于stack exchange,提问作者Rei Brown

