简体   繁体   English

如何在Javalin中验证列表主体

[英]How to validate list body in Javalin

My DELETE request accepts a list of Item s that should be deleted. 我的DELETE请求接受应删除的Item列表。

I want to validate that the request body is a valid list of Item objects. 我想验证请求正文是Item对象的有效列表。

The example given in the Javalin docs doesn't mention lists. Javalin文档给出示例未提及列表。

In order to get the code to compile, I had to do this: 为了获得编译代码,我不得不这样做:

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

The validation passes and the ctx body is printed correctly in the following line. 验证通过并在以下行中正确打印ctx正文。 The problem is, there is an unchecked assignment at getOrThrow() and indeed the loop doesn't work: 问题是,在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)

Edit: The java.util.LinkedHashMap seems to be because actually, items is of type ArrayList<LinkedHashMap<String,String>> . 编辑: java.util.LinkedHashMap似乎是因为实际上, itemsArrayList<LinkedHashMap<String,String>> In other words, Javalin didn't parse or validate the body contents at all! 换句话说,Javalin根本没有解析或验证身体内容! It only converted the Json name=value mappings into a Java Map. 它只将Json name=value映射转换为Java Map。

What would be a better way to validate the incoming Json and parse it to a list of Item s? 什么是更好的方法来验证传入的Json并将其解析为Item的列表?

I've tested on Javalin 2.6.0 and 2.8.0. 我在Javalin 2.6.0和2.8.0上测试过。

What I had missed, and can't find in the Javalin docs, was that I have to use array types rather than parameterized Collection types. 我错过了,在Javalin文档中找不到的是,我必须使用数组类型而不是参数化的Collection类型。 This works: 这有效:

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

Still, would love to know why this is - I suspect it is related to Java's type system somehow? 不过,很想知道为什么会这样 - 我怀疑它与Java的类型系统有什么关系?

I could also directly access the Jackson ObjectMapper object and use it like you would use Jackson . 我也可以直接访问Jackson ObjectMapper对象并像使用Jackson一样使用它。 The drawback is that I don't benefit from Javalin's automatic throwing of BadRequestResponse etc. I think using array types is a small price to pay for this. 缺点是我没有受益于Javalin自动抛出BadRequestResponse等。我认为使用数组类型是一个很小的代价。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM