gpt4 book ai didi

jakarta-ee - 如何使用 json-b 反序列化接口(interface)?

转载 作者:行者123 更新时间:2023-12-03 21:02:57 25 4
gpt4 key购买 nike

我正在改编这个 jackson 代码:

@JsonDeserialize(as = EntityImpl.class)
public interface Entity { ... }

原始代码运行良好,即使对于嵌套的 Entity 对象也是如此。

如何对新的 json-b 规范做同样的事情?我尝试使用 @JsonbTypeDeserializer 但是
  • 这真的是要走的路吗?它似乎缺乏仅指定一个类的简单性。
  • 它似乎不适用于嵌套实体,这是我最大的问题:

    javax.json.bind.JsonbException: Can't infer a type for unmarshalling into: Entity

  • 实体上未拾取注释。我必须使用 JsonbConfig::withDeserializers 手动添加。

  • 这是我的反序列化代码:
    public class EntityDeserializer implements JsonbDeserializer<Entity> {

    @Override
    public Entity deserialize(JsonParser parser, DeserializationContextdeserializationContext, Type runtimeType) {
    Class<? extends Entity> entityClass = EntityImpl.class.asSubclass(Entity.class);
    return deserializationContext.deserialize(entityClass, parser);
    }
    }

    非常感谢任何提示或帮助:-)

    最佳答案

    @Dmitry 给出的答案对我帮助很大,但它有两个缺陷:

    1:使用 JSON 中的完整类名是一个严重的安全问题。攻击者可以让您反序列化任意类,并且某些类可以导致远程代码执行。你 必须使用映射(或将允许的子类列入白名单)。例如。:

    [
    {
    "square": {
    "side": 2.0
    }
    },
    {
    "circle": {
    "radius": 5.0
    }
    }
    ]

    2:在类型中包装实际对象可能不是我们希望 JSON 的样子。或者当我们从不同的系统接收 JSON 时,我们通常会得到不同的结构,例如与 @type field 。并且字段顺序在 JSON 中没有定义;生产者有时可能会发送 @type最后的。例如。
    [
    {
    "@type":"square",
    "side": 2.0
    },
    {
    "radius": 5.0,
    "@type":"circle"
    }
    ]

    我找到的解决方案是这样的:

    public class ShapeDeserializer implements JsonbDeserializer<Shape> {
    @Override public Shape deserialize(JsonParser parser, DeserializationContext ctx, Type rtType) {
    JsonObject value = parser.getObject();
    String type = value.getString("@type", "null");
    return JSONB.fromJson(value.toString(), classFor(type));
    }

    private Class<? extends Shape> classFor(String type) {
    switch (type) {
    case "circle":
    return Circle.class;
    case "square":
    return Square.class;
    default:
    throw new JsonbException("unknown shape type " + type);
    }
    }
    }

    请注意,从 Parser 读取前进光标;但是我们需要重新读取完整的对象——记住: @type可能不是第一个字段。由于没有用于重置光标的 API,我通过调用 toString 生成了一个新的 JSON 字符串。并用它来启动一个新的解析器。这并不完美,但性能影响应该是可以接受的。 YMMV。

    而且我渴望看到 JSON-B 直接支持的多态类型,正如所讨论的 here .

    关于jakarta-ee - 如何使用 json-b 反序列化接口(interface)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46050845/

    25 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com