从POJO到vertx.io的JsonObject的优雅Map?

m4pnthwp  于 2023-06-07  发布在  其他
关注(0)|答案(6)|浏览(133)

我目前正在开发一个vertx.io应用程序,希望使用provide mongo API进行数据存储。我目前在JsonObject类的基础上有一个相当笨拙的抽象,其中所有的getset方法都被替换为以下内容:

this.backingObject.get(KEY_FOR_THIS_PROPERTY);

这一切都很好,现在很好,但它不会特别好地扩展。它看起来也很脏,特别是在使用嵌套数组或对象时。例如,如果我想只在已知实际数据时才能填充字段,我必须检查数组是否存在,以及它是否没有创建它并将其存储在对象中。然后我可以在列表中添加一个元素。例如:

if (this.backingObject.getJsonArray(KEY_LIST) == null) {
    this.backingObject.put(KEY_LIST, new JsonArray());
}
this.backingObject.getJsonArray(KEY_LIST).add(p.getBackingObject());

我已经考虑过潜在的解决方案,但并不特别喜欢其中任何一个。也就是说,我可以使用Gson或一些类似的支持注解的库来处理加载对象,以便在代码中操作数据,然后使用Gson和Vertx的serialize和unserialize函数在格式(vertx to load data -> json string -> gson to parse json into pojos -> make changes -> serialize to json string -> parse with vertx and save)之间进行转换,但这是一个非常粗糙和低效的工作流程。我也可以提出某种抽象的 Package 器,扩展/实现vertx json库,但将所有功能传递给gson,但这似乎也需要做很多工作。
有没有什么好的方法可以使用vertx实现更友好和更易于维护的序列化?

zfciruhq

zfciruhq1#

我刚刚向Vert.x提交了一个补丁,它定义了两个新的方便函数,用于在JsonObject和Java对象示例之间进行转换,而不会因为中间JSON字符串表示而效率低下。这将在版本3.4中。

// Create a JsonObject from the fields of a Java object.
// Faster than calling `new JsonObject(Json.encode(obj))`.
public static JsonObject mapFrom(Object obj)

// Instantiate a Java object from a JsonObject.
// Faster than calling `Json.decodeValue(Json.encode(jsonObject), type)`.
public <T> T mapTo(Class<T> type)

在内部,它使用ObjectMapper#convertValue(...),请参阅Tim Putnam的回答以了解这种方法的注意事项。密码在这里。

m2xkgtsf

m2xkgtsf2#

我相信Jackson的ObjectMapper.convertValue(..)函数不会通过String进行转换,而且Vert.x使用Jackson来管理JsonObject。
JsonObject只有一个表示值的底层Map,可通过JsonObject.getMap()访问,以及io.vertx.core.json.Json中公共ObjectMapper示例上的Jackson序列化器/解串器。
要在JsonObject和用Jackson可序列化的Pojos表示的数据模型之间切换,您可以执行以下操作:
JsonObject myVertxMsg = ... MyPojo pojo = Json.mapper.convertValue ( myVertxMsg.getMap(), MyPojo.class );
我想这比通过String更有效(但这只是一个猜测),我讨厌改变数据类只是为了适应环境的想法,所以它取决于上下文形式与性能。
要从Pojo转换为JsonObject,请使用Jackson转换为map,然后在JsonObject上使用构造函数:
JsonObject myobj = new JsonObject ( Json.mapper.convertValue ( pojo, Map.class ));

  • 如果在定义中隐含嵌套的JsonObjects或JsonArray对象,则默认情况下,它们将被示例化为Maps和List。当你访问指定这些类型的字段时,JsonObject会在内部重新 Package 这些类型(例如使用getJsonArray(..)。
  • 由于JsonObject是自由格式的,并且您正在转换为静态类型,因此可能会遇到一些不需要的UnrecognizedPropertyException。创建您自己的ObjectMapper,添加vertx JsonObjectSerializer和JsonArraySerializer,然后进行配置更改以适应(例如Jackson中的DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES),这可能很有用。
agyaoht7

agyaoht73#

不确定我是否正确理解了你的意思,但听起来你似乎在试图找到一种将POJO转换为JsonObject的简单方法?
因此,我们有很多pojo,我们将它们作为JsonObject发送到EventBus
我发现最简单的方法是使用vert.xJson类,它有大量的帮助器方法可以在JsonStrings之间进行转换

JsonObject jsonObject = new JsonObject(Json.encode(myPojo));

有时你需要添加一些自定义的(反)序列化器,但是我们总是坚持使用Jackson--这就是Vert.x所使用的,所以它们可以开箱即用。
我们实际上做的是提供一个如下所示的接口:

public JsonObjectSerializable {
    public JsonObject toJson();
}

我们所有需要通过EventBus发送的pojo都必须实现这个接口。
然后我们的EventBus发送代码看起来像(简化):

public <T extends JsonObjectSerializable> Response<T> dispatch(T eventPayload);

此外,由于我们通常不对Pojo进行单元测试,因此添加此interface可以鼓励开发人员对其转换进行单元测试。
希望这能帮上忙
威尔

vwhgwdsa

vwhgwdsa4#

试试这个:

io.vertx.core.json.Json.mapper.convertValue(json.getMap(), cls)
xxhby3vn

xxhby3vn5#

我认为使用你所描述的Gson是目前最好的解决方案。
虽然我同意如果Vert.x中包含协议层,它确实会是第一名,但使用Gson可以使您的服务器内部组织得很好,不太可能成为性能瓶颈。
当且仅当此策略成为性能瓶颈时,您才需要设计更好的解决方案。在此之前的任何事情都是过早的优化。
我的两分钱。

h7appiyu

h7appiyu6#

可以使用静态函数mapFrom

JsonObject.mapFrom(object)

相关问题