3
votes

Contrôleur Micronaut avec pagination utilisant Pageable

J'essaye d'utiliser un contrôleur Micronaut avec pagination. Micronaut-Data a cette manière inspirée du printemps pour accéder aux référentiels à l'aide de Classe paginable et renvoyant une Page

Le problème survient lorsque vous souhaitez afficher ces données paginées. Je n'ai pas pu créer un appel au contrôleur avec pagination. Ici, j'ai un contrôleur simple:

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

Je m'attendrais à pouvoir l'appeler avec quelque chose comme ça. Mais actuellement, l'enregistreur montre que pageable est toujours nul:

    @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
        }

Ce serait encore mieux si nous pouvions le tester avec quelque chose comme:

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


0 commentaires

3 Réponses :


1
votes

"/ test {? pageable}" Signifie la liaison à une seule valeur de requête appelée pageable

"/ test {? pageable *}" Signifie de lier toutes les valeurs de requête à un argument appelé pageable

Vous voulez ce dernier


2 commentaires

Salut James, je viens de le tester et ne semble pas fonctionner. Il compile mais l'argument paginable reçu est nul.


C'est certainement la voie à suivre. Il doit y avoir un autre problème avec votre application



3
votes

Dans mon application, j'accepte également Pageable et je n'ai aucun problème avec celui-ci. La différence entre le mien et le vôtre est:

  1. Mon chemin est juste @Get ("/ test") , c'est-à-dire pas de partie {pageable} .
  2. Je ne rends pas mon Pageable en tant que @Nullable . D'après ce que je peux tracer à partir du code micronaute, il ne traite pas Pageable comme n'importe quel autre objet. Il a un traitement spécial pour cela (comme tester si le type d'argument est Pageable et si c'est le cas, alors faites certaines choses).

Pouvez-vous essayer ces deux choses?


1 commentaires

Peut-être que j'ai besoin de changer quelque chose de plus parce que j'obtiens: io.micronaut.http.client.exceptions.HttpClientResponseExcept‌ ion: Argument requis [Pageable pageable] non spécifié



3
votes

Le problème a été résolu en ajoutant la dépendance suivante:

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

Ma couche de contrôleur avait accès au micronaut-data-model mais ce fichier contient la classe importante PageableRequestArgumentBinder . Juste en étant dans le classpath, il sera automatiquement injecté comme un classeur sans avoir besoin de configuration supplémentaire.

Et oui, Free See avait raison et maintenant je peux supprimer l'argument paginable du chemin et l'argument de la méthode n'a pas besoin d'être @Nullable:

micronaut:
  data:
    pageable:
     max-page-size: 500
  • DEFAULT_PAGE_PARAMETER "page"
  • DEFAULT_SIZE_PARAMETER "taille"
  • DEFAULT_SORT_PARAMETER "tri"

Si vous souhaitez utiliser différents paramètres, vous pouvez le modifier avec les propriétés:

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

Et vous pouvez le tester avec

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

Et, pour améliorer encore les choses, le client peut convertir le résultat en une page en utilisant la méthode pageOf qui renvoie Argument>


0 commentaires