如何在 Javalin中验证列表正文



我的删除请求接受应删除的Item列表。

我想验证请求正文是否是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>>型。换句话说,Javalin根本没有解析或验证正文内容!它只将 Json name=value映射转换为 Java Map。

验证传入的 Json 并将其解析为Item列表的更好方法是什么?

我已经在 Javalin 2.6.0 和 2.8.0 上进行了测试。

我错过了,并且在 Javalin 文档中找不到的是我必须使用数组类型而不是参数化集合类型。这有效:

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

不过,很想知道为什么会这样 - 我怀疑它以某种方式与 Java 的类型系统有关?

我也可以直接访问 Jackson ObjectMapper 对象,并像使用 Jackson 一样使用它。缺点是我没有从Javalin的自动投掷BadRequestResponse等中受益。我认为使用数组类型为此付出的代价很小。

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

最新更新