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

Micronaut控制器使用Pageable分页调用及序列化问题求助

解决Micronaut控制器分页参数绑定与Page对象序列化问题

一、修复Pageable参数始终为null的问题

你遇到的Pageable参数一直为null的情况,主要需要从依赖配置、路由写法和参数命名这几个方向调整:

1. 确认Micronaut Data依赖配置

首先要保证项目里引入了Micronaut Data的核心依赖(以Gradle为例):

implementation("io.micronaut.data:micronaut-data-jpa") // 对应你使用的数据源模块,比如mongodb、jdbc等
annotationProcessor("io.micronaut.data:micronaut-data-processor")

Maven项目对应添加相关依赖即可,Pageable的参数绑定逻辑需要这些依赖提供的支持。

2. 修正控制器路由与参数绑定

你控制器路径里写的/test{?pageable}是多余的,Micronaut会自动把请求参数绑定到Pageable对象上,但要注意默认参数名是page(页码从0开始)和size,而不是你用的number。

修正后的控制器代码:

@Controller
public class PageableController {
    private static final Logger LOGGER = LoggerFactory.getLogger(PageableController.class);

    // 移除路径中的{?pageable},直接接收Pageable参数
    @Get(produces = MediaType.APPLICATION_JSON, value = "/test")
    // 用@PageableDefault设置默认分页参数,避免pageable为null
    public Page<String> getNames(@PageableDefault(size = 10, page = 0) Pageable pageable) {
        LOGGER.info("pageable {}", pageable);
        return Page.of(Arrays.asList("foo", "bar"), pageable, 2);
    }
}

现在你可以用/test?size=20&page=2来请求,Pageable就能正确绑定了。如果一定要用number作为页码参数名,可以在配置文件中修改:

micronaut.data.pageable.parameter-names.page=number

3. 测试代码修正

你的测试里用了&amp;(HTML转义字符),直接用&即可:

@Test
void callsWithPageable() {
    String uri = "/test?size=20&page=2";
    String orders = client.toBlocking().retrieve(HttpRequest.GET(uri));
    // 后续断言逻辑
}

二、修复Page对象序列化/反序列化问题

Micronaut默认的Jackson序列化器对Page对象的支持需要额外配置,你可以通过以下两种方式解决:

1. 注册Page类型的Jackson模块

创建一个配置类,注册Micronaut Data提供的PageModule,让Jackson能正确处理Page对象:

@Singleton
public class JacksonConfiguration implements BeanCreatedEventListener<ObjectMapper> {
    @Override
    public ObjectMapper onCreated(BeanCreatedEvent<ObjectMapper> event) {
        ObjectMapper mapper = event.getBean();
        mapper.registerModule(new PageModule());
        return mapper;
    }
}

这种方式是全局生效的,后续所有Page对象的序列化/反序列化都会正常工作。

2. 调整自定义Argument解析逻辑

如果不想修改Jackson配置,可以修正你的pageOf方法的泛型写法:

private static <T> Argument<Page<T>> pageOf(Class<T> type) {
    return Argument.of(Page.class, type);
}

不过更推荐第一种方式,能避免重复编写解析逻辑。

三、额外注意事项

  • 尽量使用Micronaut的最新稳定版,旧版本可能存在分页参数绑定的Bug(你提到的相关Bug应该已经在新版本中修复)。
  • 如果使用响应式编程(比如RxJava),可以将返回类型改为Single<Page<T>>或Flowable<Page<T>>,适配客户端的调用方式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.14 07:23:39