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. 测试代码修正
你的测试里用了&(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
相关产品推荐
相关产品推荐

