【问题标题】:Map json data to corresponding Class将json数据映射到对应的Class
【发布时间】:2018-04-11 08:40:40
【问题描述】:

我有一个字符串格式的 JSON 数据。这个 JSON 数据来自一个 JMS 队列。 例如:-

String msg=" {"id":"4","item":"GOT","description":"hello"}";

我正在使用 Gson 库将此 JSON 字符串转换为相应的类对象

Gson g = new Gson();   
BooksTable b1 = g.fromJson(msg, BooksTable.class); //BooksTable is a POJO class with getter setters
addBook(b1);   //used to insert object into the database Books table

现在的问题是这个 json 可以是书籍表或具有格式 json 的事务表

String msg=" {"id":"2","name":"deposit","purpose":"savings"}";

我想根据 JSON 字符串将对象动态映射到相应的类。

例如:如果 Books JSON 来,则将其发送到 Books 表 如果 Transaction JSON 来,则将其发送到 Transaction 表。

我该怎么做?如果 apache camel 可以做到这一点,请告诉如何处理? 任何方法都将不胜感激。

【问题讨论】:

  • 没关系,忽略我的回答,我才意识到这与你的问题无关。
  • 你不能根据你的消息来源做一个简单的if()else 吗?我认为你有类似String msg = someDBHandler.doThings() 的东西?如果你不能这样做,你也许可以简单地扫描你的 json 以获得唯一的键,但我不推荐这样做。例如JSONObject obj = new JSONObject(msg); if(obj.has('purpose')) { // Do TransactionTable things } else if(obj.has('item')) { // Do BookTable things }
  • 是的,但我提到的用例是一个简单的用例。如果有数百个表,每个表有多个列怎么办。匹配每一列不会有效率。
  • 好吧,这更难处理,如果您返回了一个基本类型为? 的对象,那么以后您将如何处理这个问题?我可以想象像Object j = g.fromJson(msg, Class.forName('some.package.identifierFromMessageOrSomething')); 这样的东西,但从长远来看它可能没有多大帮助。

标签: java json apache-camel gson jms


【解决方案1】:

首先使用 JsonParser 解析 JSON,以便您检查它,然后使用 Gson 解组为适当的对象类型。

public class Test {
    public static void main(String[] args) {
        process("{\"id\":\"4\",\"item\":\"GOT\",\"description\":\"hello\"}");
        process("{\"id\":\"2\",\"name\":\"deposit\",\"purpose\":\"savings\"}");
    }
    private static void process(String json) {
        JsonObject object = new JsonParser().parse(json).getAsJsonObject();
        if (object.has("item")) {
            Book book = new Gson().fromJson(object, Book.class);
            System.out.println(book);
        } else if (object.has("name")) {
            Transaction transaction = new Gson().fromJson(object, Transaction.class);
            System.out.println(transaction);
        } else {
            System.out.println("Unknown JSON: " + json);
        }
    }
}
class Book {
    private int id;
    private String item;
    private String description;
    @Override
    public String toString() {
        return "Book[id=" + this.id +
                  ", item=" + this.item +
                  ", description=" + this.description + "]";
    }
}
class Transaction {
    private int id;
    private String name;
    private String purpose;
    @Override
    public String toString() {
        return "Transaction[id=" + this.id +
                         ", name=" + this.name +
                         ", purpose=" + this.purpose + "]";
    }
}

输出

Book[id=4, item=GOT, description=hello]
Transaction[id=2, name=deposit, purpose=savings]

【讨论】:

  • 这适用于一个简单的用例。考虑一下我有 3 个包含列的表:- 表 1 - id、item、name 表 2 - id、item、description 表 3 - id、用途、项目和许多其他具有许多相似列的表
  • @ShubhamChopra 我不明白你的意思。您要求编写代码以仅根据 JSON 文本解组为不同的对象类型,没有其他指导信息。这就是答案。如果您只有 JSON 文本,那么确定检测逻辑取决于您。如果您有更多信息而不是 JSON 文本,那么您的问题应该是这样说的,然后您也将基于该信息进行检测。
【解决方案2】:

您可以使用camel-jsonpath 来检查 JSON 字符串是否包含某个字段:

<choice>
    <when>
        <jsonpath suppressExceptions="true">$.item</jsonpath>
        <!-- Unmarshal to Book -->
    </when>
    <when>
        <jsonpath suppressExceptions="true">$.name</jsonpath>
        <!-- Unmarshal to Transaction -->
    </when>
</choice>

【讨论】:

    【解决方案3】:

    您可以尝试查看这个对骆驼的扩展——JSON Schema Validator Component。它应该与骆驼中的原始验证器一样工作,但它允许您根据架构验证消息体。

    【讨论】:

      猜你喜欢
      • 2019-05-27
      • 2014-03-15
      • 1970-01-01
      • 1970-01-01
      • 2012-04-23
      • 2020-03-11
      • 2011-08-05
      • 2020-06-26
      • 2017-12-24
      相关资源
      最近更新 更多