You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

配置Spring Data分页从1开始后,API返回页码仍为0的问题

问题分析

你配置的spring.data.web.pageable.one-indexed-parameters=true仅作用于请求参数解析阶段:当客户端传入page=1时,Spring会自动将其转换为Spring Data内部使用的0基页码(即pageNumber=0),但这个配置不会自动修改响应中Page对象的页码输出逻辑——PageImpl默认序列化时仍会输出内部的0基页码,这就是你看到响应中pageNumber为0的原因。

解决方案

要让响应返回1基页码,需要手动调整Page对象中的页码信息,以下是两种可行方案:

方案1:构造PageImpl时替换为1基的Pageable

在创建返回的PageImpl对象时,基于原pageable构造一个页码+1的新Pageable,替换掉原有的0基pageable:

@GetMapping(value = "/alluser", produces = MediaType.APPLICATION_JSON_VALUE)
public Page<User> getUserinfo(Pageable pageable) {
    Page<User> userPage = userService.getAllUserInfo(pageable);
    // 用Page自带的map方法简化DTO转换(替代stream操作)
    List<User> userResultList = userPage.map(converterService::convertToDto).getContent();
    
    // 构造1基的Pageable:页码+1,保留原分页大小和排序规则
    Pageable oneIndexedPageable = PageRequest.of(
        pageable.getPageNumber() + 1,
        pageable.getPageSize(),
        pageable.getSort()
    );
    
    // 用新的1基Pageable创建返回的Page对象
    Page<User> userDtoPage = new PageImpl<>(userResultList, oneIndexedPageable, userPage.getTotalElements());
    return userDtoPage;
}

方案2:自定义Jackson序列化规则(全局生效)

如果希望所有Page对象的响应都自动输出1基页码,可以自定义Jackson序列化器,修改number(对应响应中的pageNumber)的输出值:

  1. 创建自定义序列化器:
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 OneIndexedPageSerializer extends JsonSerializer<Page<?>> {
    @Override
    public void serialize(Page<?> page, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        gen.writeStartObject();
        // 序列化内容列表
        gen.writeObjectField("content", page.getContent());
        // 序列化1基页码
        gen.writeNumberField("number", page.getNumber() + 1);
        gen.writeNumberField("pageNumber", page.getNumber() + 1);
        // 序列化其他分页属性
        gen.writeNumberField("size", page.getSize());
        gen.writeNumberField("totalElements", page.getTotalElements());
        gen.writeNumberField("totalPages", page.getTotalPages());
        gen.writeBooleanField("first", page.isFirst());
        gen.writeBooleanField("last", page.isLast());
        gen.writeNumberField("numberOfElements", page.getNumberOfElements());
        gen.writeBooleanField("empty", page.isEmpty());
        // 序列化pageable和sort对象(调整pageable内的页码)
        gen.writeObjectField("sort", page.getSort());
        gen.writeStartObjectField("pageable");
        gen.writeObjectField("sort", page.getSort());
        gen.writeNumberField("offset", page.getOffset());
        gen.writeNumberField("pageNumber", page.getNumber() + 1);
        gen.writeNumberField("pageSize", page.getSize());
        gen.writeBooleanField("paged", true);
        gen.writeBooleanField("unpaged", false);
        gen.writeEndObject();
        gen.writeEndObject();
    }
}
  1. 注册序列化器到Spring:
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.domain.Page;
import com.fasterxml.jackson.databind.module.SimpleModule;

@Configuration
public class JacksonConfig {
    @Bean
    public SimpleModule oneIndexedPageModule() {
        SimpleModule module = new SimpleModule();
        module.addSerializer(Page.class, new OneIndexedPageSerializer());
        return module;
    }
}

这种方案无需修改业务代码,全局生效,适合所有分页接口统一返回1基页码的场景。

额外优化:简化DTO转换

你当前的stream().map()可以替换为Spring Data Page自带的map()方法,代码更简洁:

// 替代原有stream操作
Page<User> userDtoPage = userPage.map(userObj -> converterService.convertToDto(userObj));

内容的提问来源于stack exchange,提问作者sundar saba

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 09:28:08