使用 Pageable 进行分页的 Micronaut 控制器
Micronaut controller with pagination using Pageable
我正在尝试使用带分页功能的 Micronaut 控制器。 Micronaut-Data 有 this Spring inspired way to access the repositories using the Pageable class and returning a Page
当你想显示这个分页数据时,问题就来了。我无法创建带有分页的控制器调用。这里我有一个简单的控制器:
@Controller
public class PageableController {
private static final Logger LOGGER = LoggerFactory.getLogger(PageableController.class);
@Get(produces = APPLICATION_JSON, value = "/test{?pageable}")
public Page<String> getNames(@Nullable Pageable pageable) {
LOGGER.info("pageable {}", pageable);
if( pageable == null){
return Page.of(Arrays.asList("foo", "bar"), Pageable.UNPAGED, 2);
}else{
return Page.of(Arrays.asList("foo", "bar"), pageable, 2);
}
}
}
我希望能够用这样的方式调用它。但目前记录器显示可分页始终为空:
@MicronautTest
class PageableControllerTest {
@Inject
@Client("/")
private RxHttpClient client;
@Test
void callsWithPageable() {
String uri = "/test?size=20&number=2";
String orders = client.toBlocking().retrieve(HttpRequest.GET(uri));
//TODO, assert orders and pagination
}
如果我们可以用类似的东西来测试它会更好:
@Test
void callsWithPageableParsingJson() {
String uri = "/test?size=20&number=2";
//This fails to parse as it can't build pages.
Page<String> pages = client.toBlocking().retrieve(HttpRequest.GET(uri), pageOf(String.class));
assertThat(pages.getSize(), is(2));
assertThat(pages.getContent(), contains("foo", "bar"));
}
// Inspired by Argument.listOf
private static <T> Argument<Page<T>> pageOf(Class<T> type) {
return Argument.of((Class<Page<T>>) ((Class) Page.class), type);
}
这 Micronaut bug 表明正确的分页方式是使用 Micronaut 数据
"/test{?pageable}"
表示绑定到一个名为 pageable
的单个查询值
"/test{?pageable*}"
表示将所有查询值绑定到一个名为 pageable
的参数
你想要后者
在我的申请中,我也接受 Pageable
,我对此没有任何问题。我和你的区别是:
- 我的路径只是
@Get("/test")
即没有 {pageable}
部分。
- 我没有让我的
Pageable
成为 @Nullable
。从我可以从 micronaut 代码中追踪到的,它不会像对待任何其他对象一样对待 Pageable
。它有特殊的处理方式(比如测试参数类型是否为 Pageable
,如果是,则执行某些操作)。
你能试试这两件事吗?
问题已通过添加以下依赖项解决:
<dependency>
<groupId>io.micronaut.data</groupId>
<artifactId>micronaut-data-runtime</artifactId>
<version>1.0.0.M1</version>
</dependency>
我的控制器层可以访问 micronaut-data-model 但这个 jar 包含重要的 class PageableRequestArgumentBinder。只要在 classpath 中,它就会自动作为活页夹注入,无需额外配置。
是的,Free See 是正确的,现在我可以从路径中删除可分页参数,并且方法中的参数不需要是 @Nullable :
@Controller
public class PageableController {
private static final Logger LOGGER = LoggerFactory.getLogger(PageableController.class);
@Get(produces = APPLICATION_JSON, value = "/test")
public Page<String> getNames(Pageable pageable) {
LOGGER.info("pageable {}", pageable);
return Page.of(Arrays.asList("foo", "bar", "baz"), pageable, 3);
}
要调用它,我们将使用 standard parameters names defined in DataConfiguration.PageableConfiguration。
- DEFAULT_PAGE_PARAMETER "page"
- DEFAULT_SIZE_PARAMETER "size"
- DEFAULT_SORT_PARAMETER "sort"
如果您想使用不同的参数,您可以使用属性进行更改:
micronaut:
data:
pageable:
max-page-size: 500
你可以用
测试它
@Test
void callsWithPageable() {
String uri = "/test?page=1&size=2";
Page<String> pages = client.toBlocking().retrieve(HttpRequest.GET(uri), pageOf(String.class));
assertThat(pages.getPageNumber(), is(1));
assertThat(pages.getTotalPages(), is(2));
assertThat(pages.getSize(), is(2));
assertThat(pages.getContent(), contains("foo", "bar", "baz"));
}
而且,为了使事情变得更好,客户端可以使用 returns 参数>
的 pageOf 方法将结果转换为页面
我正在尝试使用带分页功能的 Micronaut 控制器。 Micronaut-Data 有 this Spring inspired way to access the repositories using the Pageable class and returning a Page
当你想显示这个分页数据时,问题就来了。我无法创建带有分页的控制器调用。这里我有一个简单的控制器:
@Controller
public class PageableController {
private static final Logger LOGGER = LoggerFactory.getLogger(PageableController.class);
@Get(produces = APPLICATION_JSON, value = "/test{?pageable}")
public Page<String> getNames(@Nullable Pageable pageable) {
LOGGER.info("pageable {}", pageable);
if( pageable == null){
return Page.of(Arrays.asList("foo", "bar"), Pageable.UNPAGED, 2);
}else{
return Page.of(Arrays.asList("foo", "bar"), pageable, 2);
}
}
}
我希望能够用这样的方式调用它。但目前记录器显示可分页始终为空:
@MicronautTest
class PageableControllerTest {
@Inject
@Client("/")
private RxHttpClient client;
@Test
void callsWithPageable() {
String uri = "/test?size=20&number=2";
String orders = client.toBlocking().retrieve(HttpRequest.GET(uri));
//TODO, assert orders and pagination
}
如果我们可以用类似的东西来测试它会更好:
@Test
void callsWithPageableParsingJson() {
String uri = "/test?size=20&number=2";
//This fails to parse as it can't build pages.
Page<String> pages = client.toBlocking().retrieve(HttpRequest.GET(uri), pageOf(String.class));
assertThat(pages.getSize(), is(2));
assertThat(pages.getContent(), contains("foo", "bar"));
}
// Inspired by Argument.listOf
private static <T> Argument<Page<T>> pageOf(Class<T> type) {
return Argument.of((Class<Page<T>>) ((Class) Page.class), type);
}
这 Micronaut bug 表明正确的分页方式是使用 Micronaut 数据
"/test{?pageable}"
表示绑定到一个名为 pageable
"/test{?pageable*}"
表示将所有查询值绑定到一个名为 pageable
你想要后者
在我的申请中,我也接受 Pageable
,我对此没有任何问题。我和你的区别是:
- 我的路径只是
@Get("/test")
即没有{pageable}
部分。 - 我没有让我的
Pageable
成为@Nullable
。从我可以从 micronaut 代码中追踪到的,它不会像对待任何其他对象一样对待Pageable
。它有特殊的处理方式(比如测试参数类型是否为Pageable
,如果是,则执行某些操作)。
你能试试这两件事吗?
问题已通过添加以下依赖项解决:
<dependency>
<groupId>io.micronaut.data</groupId>
<artifactId>micronaut-data-runtime</artifactId>
<version>1.0.0.M1</version>
</dependency>
我的控制器层可以访问 micronaut-data-model 但这个 jar 包含重要的 class PageableRequestArgumentBinder。只要在 classpath 中,它就会自动作为活页夹注入,无需额外配置。
是的,Free See 是正确的,现在我可以从路径中删除可分页参数,并且方法中的参数不需要是 @Nullable :
@Controller
public class PageableController {
private static final Logger LOGGER = LoggerFactory.getLogger(PageableController.class);
@Get(produces = APPLICATION_JSON, value = "/test")
public Page<String> getNames(Pageable pageable) {
LOGGER.info("pageable {}", pageable);
return Page.of(Arrays.asList("foo", "bar", "baz"), pageable, 3);
}
要调用它,我们将使用 standard parameters names defined in DataConfiguration.PageableConfiguration。
- DEFAULT_PAGE_PARAMETER "page"
- DEFAULT_SIZE_PARAMETER "size"
- DEFAULT_SORT_PARAMETER "sort"
如果您想使用不同的参数,您可以使用属性进行更改:
micronaut:
data:
pageable:
max-page-size: 500
你可以用
测试它 @Test
void callsWithPageable() {
String uri = "/test?page=1&size=2";
Page<String> pages = client.toBlocking().retrieve(HttpRequest.GET(uri), pageOf(String.class));
assertThat(pages.getPageNumber(), is(1));
assertThat(pages.getTotalPages(), is(2));
assertThat(pages.getSize(), is(2));
assertThat(pages.getContent(), contains("foo", "bar", "baz"));
}
而且,为了使事情变得更好,客户端可以使用 returns 参数>
的 pageOf 方法将结果转换为页面