【问题标题】:Micronaut controller with pagination using Pageable使用 Pageable 进行分页的 Micronaut 控制器
【发布时间】:2019-08-30 12:15:30
【问题描述】:

我正在尝试使用带有分页功能的 Micronaut 控制器。 Micronaut-Data 有 this Spring inspired way 使用 Pageable 类访问存储库并返回 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 Data

【问题讨论】:

    标签: pagination controller micronaut


    【解决方案1】:

    通过添加以下依赖项解决了问题:

        <dependency>
           <groupId>io.micronaut.data</groupId>
           <artifactId>micronaut-data-runtime</artifactId>
           <version>1.0.0.M1</version>
        </dependency>
    

    我的控制器层可以访问 micronaut-data-model,但这个 jar 包含重要的类 PageableRequestArgumentBinder。只要成为类路径,它就会自动作为活页夹注入,无需额外配置。

    是的,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);
            }
    

    我们使用DataConfiguration.PageableConfiguration 中定义的standard parameters names 来称呼它。

    • DEFAULT_PAGE_PARAMETER“页面”
    • DEFAULT_SIZE_PARAMETER "大小"
    • DEFAULT_SORT_PARAMETER "排序"

    如果你想使用不同的参数,你可以通过属性来改变它:

    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"));
        }
    

    而且,为了让事情变得更好,客户端可以使用返回参数的 pageOf 方法将结果转换为页面>

    【讨论】:

      【解决方案2】:

      在我的申请中,我也接受Pageable,我对此没有任何问题。我和你的区别是:

      1. 我的路径只是 @Get("/test"),即没有 {pageable} 部分。
      2. 我不会将我的Pageable 设为@Nullable。从我从 micronaut 代码中可以看出,它不会像对待任何其他对象一样对待 Pageable。它对其进行了特殊处理(例如测试参数类型是否为Pageable,如果是,则执行某些操作)。

      你可以试试这两个东西吗?

      【讨论】:

      • 可能我需要更改更多内容,因为我得到:io.micronaut.http.client.exceptions.HttpClientResponseException: 未指定必需参数 [Pageable pageable]
      【解决方案3】:

      "/test{?pageable}" 表示绑定到一个名为 pageable 的单个查询值

      "/test{?pageable*}" 表示将所有查询值绑定到一个名为 pageable 的参数

      你想要后者

      【讨论】:

      • 嗨,詹姆斯,我刚刚测试过它,但似乎不起作用。它编译但接收到的可分页参数为空。
      • 这绝对是要走的路。你的应用肯定有其他问题
      猜你喜欢
      • 2013-03-30
      • 1970-01-01
      • 1970-01-01
      • 2019-04-22
      • 2018-02-16
      • 2014-08-27
      • 1970-01-01
      • 1970-01-01
      • 2015-11-13
      相关资源
      最近更新 更多