Как проверить тело списка в Джавалине - PullRequest
0 голосов
/ 27 марта 2019

Мой запрос DELETE принимает список Item s, который должен быть удален.

Я хочу проверить, что тело запроса является допустимым списком Item объектов.

пример, приведенный в документации Javalin , не содержит списков.

Чтобы получить код для компиляции, мне нужно было сделать следующее:

    TypedValidator<List> requestValidator = ctx.validatedBodyAsClass(List.class);
    List<Item> items = requestValidator.getOrThrow();
    logger.info("Received delete request for {}", Arrays.toString(items.toArray()));
    logger.info("items is type {}", items.getClass());
    for (Item item : items) {
        logger.info("Deleting {}", item.name);
    }

Проверкапроходит, и тело ctx печатается правильно в следующей строке.Проблема в том, что в getOrThrow() есть непроверенное назначение, и действительно, цикл не работает:

[qtp1679441380-34] INFO com.myorg.MyClass - Received delete request for [{name=FooName, type=BarType}]
[qtp1679441380-34] INFO com.ericsson.cdzm.ws.controllers.ScheduleController - items is type class java.util.ArrayList
[qtp1679441380-34] WARN io.javalin.core.ExceptionMapper - Uncaught exception
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.myorg.Item
    at  com.myorg.MyClass.deleteItems(MyClass.java:51)

Редактировать: java.util.LinkedHashMap, кажется, потому что на самом деле items имеет тип ArrayList<LinkedHashMap<String,String>>.Другими словами, Джавалин вообще не анализировал и не проверял содержимое тела!Он только преобразовал сопоставления Json name=value в карту Java.

Что может быть лучше для проверки входящего Json и анализа его в списке Item s?

IПрошёл тестирование на Javalin 2.6.0 и 2.8.0.

1 Ответ

0 голосов
/ 27 марта 2019

Что я пропустил и не могу найти в документации Javalin, так это то, что мне нужно использовать типы массивов, а не параметризованные типы коллекций.Это работает:

    TypedValidator<Item[]> requestValidator = ctx.bodyValidator(Item[].class);
    List<Item> items = Arrays.asList(requestValidator.get());

Тем не менее, хотелось бы знать, почему это так - я подозреваю, что это как-то связано с системой типов Java?

Я также мог бы напрямую получить доступ к объекту Jackson ObjectMapper и использоватьэто , как если бы вы использовали Джексона .Недостаток в том, что я не извлекаю выгоду из автоматического бросания Javalin'а BadRequestResponse и т. Д. Я думаю, что использование типов массива - небольшая цена за это.

    try {
        List<ScheduleRequest> items =  JavalinJackson.getObjectMapper().readValue(ctx.body(), new TypeReference<List<ScheduleRequest>>(){});
    } catch (IOException e) {
       throw new BadRequestResponse(e.getMessage());
    }
...