Java JSON 库支持在没有模式的情况下获取和设置深层值吗?

标签 java json serialization jsonpath lenses

我正在调用某些服务的 API,它们返回一个巨大的 JSON,其中包含大约一百个字段和十几个嵌套对象。但是,我不需要全部。事实上,在执行 GET 或 POST 时,我确实需要 3 到 7 个字段。我非常希望避免在我的应用程序中使用这个复杂的模型只是为了序列化/反序列化几个字段。

本质上,我想实现:

  1. 将巨大的嵌套 JSON 字符串反序列化为我的平面 POJO。
  2. 使用平面 POJO 投影处理我的代码。
  3. 将我的平面 POJO 序列化到其复杂的嵌套架构。

到目前为止我的解决方案是依赖 JsonPath :

  1. 为我的平面 POJO 中的字段创建自定义注释,例如:

@JsonPathField("$.very.deeply.nested.field.value") private String theOnlyFieldIneed;

  • 创建一个 util 方法,使用反射来生成 <fieldName, JsonPath.readValue()> 的 map 我将其交给 Jackson objectMapper 来生成我的 POJO。因此,反序列化为平面 POJO 部分是可行的。

  • 但是,对于序列化,情况会更糟,因为如果字符串中不存在路径,JsonPath 会引发异常。比如,

  • // This will throw an exception: DocumentContext document = JsonPath.using(jsonPathConfig).parse("{}"); document.set("$.not.even.deepest", value);

  • 为了解决这个问题,我添加了一些原始架构作为字符串来提供给 JsonParh.parse(Pojo.Prototype),但这很丑陋、乏味且容易出错。
  • 基本上,我正在寻找 Immutable.JS 类型的行为:Collection.SetIn

    最佳答案

    您可以使用 Kson ( https://github.com/kantega/kson ),它非常简单地支持从嵌套结构中提取值。

    public class DecodeExample {
    
    public static class Address {
        final String street;
        final String zip;
    
        public Address(String street, String zip) {
            this.street = street;
            this.zip = zip;
        }
    }
    
    static class User {
        final String                name;
        final Address address;
    
        User(String name, Address address) {
            this.name = name;
            this.address = address;
        }
    }
    
    public static void main(String[] args) {
    
        final JsonDecoder<Address> adressDecoder =
          obj(
            field("street", stringDecoder),
            field("zip", stringDecoder.ensure(z -> z.length() < 5)), //You can add constraints right here in the converter
            Address::new
          );
    
    
        JsonResult<JsonValue> json =
          JsonParser.parse(jsonString);
    
        Address address =
          json.field("model").field("leader").field("address").decode(adressDecoder).orThrow(RuntimeException::new);
    
        System.out.println(address);
    
        JsonResult<Address> userAddress =
          json.field("model").field("users").index(0).field("address").decode(adressDecoder);
    
        System.out.println(userAddress);
    }
    
    }
    

    关于Java JSON 库支持在没有模式的情况下获取和设置深层值吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47169695/

    相关文章:

    java - 如何设置 Sublime text 3 在 linux 上运行和编译 java?

    java - Firebase addValueEventListener 在其他 Activity 中持续监听

    javascript - 如何使用 JQuery 使用循环插入 JSON 数据中的图像?

    python - 为什么加载 pickle 对象比加载文件花费的时间长得多?

    java - 如何在 Intellij Idea 场景生成器中使用鼠标重新定位或调整项目大小?

    java - 如何解析xml并获取特定元素的内容

    javascript - 未捕获( promise 中): Error: Error in ./搜索类搜索 - 内联模板:4:0 导致:超出最大调用堆栈大小

    json - Node.js - 我可以在 Redis 中将可写流存储为 JSON 吗?

    c - 如何在没有 x-macros 的情况下在 C 中获得类似反射的功能

    c# - WCF 无法序列化循环引用