【问题标题】:create json file dynamicly with hierarcy data使用层次结构数据动态创建 json 文件
【发布时间】:2013-06-06 08:57:16
【问题描述】:

我需要创建与以下帖子类似的 JSON 文件结构,但它需要是动态的, 当我搜索时,我发现了以下帖子,但解决方案特定于条目 1 和条目 2 我的需要是 json 的结构将完全相同,但可以获取任何实体名称,即实体名称可以是客户、地址、销售订单等,而不是条目 然后使用键值等字段进行数组。在帖子中,这些字段被硬编码在 POJO 中 但我需要提供向条目添加任何字段的能力......有一种方法可以提供动态解决方案吗?

谢谢!

Create JSON file with deep array

{
    "customer": [
        {
            "id": "0001",
            "type": "USER",
            "f1": "USER",
            "f2": "USER1",
             ....
        },
        {
            "id": "0002",
            "type": "EMP",
            "property":"Salery",
            "f5": "USER",
            "f6": "USER1",
             ....
        }
    ],
    "Address": [
        {
            "id": "0005",
            "name": "Vacation",
            "property":"user",
        },
        {
            "id": "0008",
            "name": "Work",
            "f5": "USER",
            "f6": "USER1",
                 ....
        }
    ]
}

【问题讨论】:

    标签: java json jackson gson arrays


    【解决方案1】:

    您可以使用FieldNamingStrategy 接口。它定义了 JSON 中属性名称和名称之间的映射。请看我的例子:

    import java.lang.reflect.Field;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    
    import com.google.gson.FieldNamingStrategy;
    import com.google.gson.Gson;
    import com.google.gson.GsonBuilder;
    
    public class GsonProgram {
    
        public static void main(String... args) throws Exception {
            Entry entry1 = new Entry();
            entry1.setId(1);
            entry1.setType("USER");
            entry1.setProperty("Salary");
            Entry entry2 = new Entry();
            entry2.setId(2);
            entry2.setType("EMP");
            Entry entry3 = new Entry();
            entry3.setId(2);
            entry3.setType("EMP");
            entry3.setProperty("Work");
            Entry entry4 = new Entry();
            entry4.setId(2);
            entry4.setType("EMP");
    
            EntryListContainer entryListContainer = new EntryListContainer();
            ArrayList<Entry> entryList1 = new ArrayList<Entry>();
            ArrayList<Entry> entryList2 = new ArrayList<Entry>();
    
            entryList1.add(entry1);
            entryList1.add(entry2);
            entryList2.add(entry3);
            entryList2.add(entry4);
    
            entryListContainer.setEntryList1(entryList1);
            entryListContainer.setEntryList2(entryList2);
    
            Map<String, String> mapping = new HashMap<String, String>();
            mapping.put("entryList1", "customer");
            mapping.put("entryList2", "Address");
    
            Gson gson = new GsonBuilder().serializeNulls().setFieldNamingStrategy(new DynamicFieldNamingStrategy(mapping)).create();
            System.out.println(gson.toJson(entryListContainer));
        }
    }
    
    class DynamicFieldNamingStrategy implements FieldNamingStrategy {
    
        private Map<String, String> mapping;
    
        public DynamicFieldNamingStrategy(Map<String, String> mapping) {
            this.mapping = mapping;
        }
    
        @Override
        public String translateName(Field field) {
            String newName = mapping.get(field.getName());
            if (newName != null) {
                return newName;
            }
    
            return field.getName();
        }
    }
    
    class EntryListContainer {
    
        private List<Entry> entryList1;
        private List<Entry> entryList2;
    
        public void setEntryList1(List<Entry> entryList1) {
            this.entryList1 = entryList1;
        }
    
        public List<Entry> getEntryList1() {
            return entryList1;
        }
    
        public void setEntryList2(List<Entry> entryList2) {
            this.entryList2 = entryList2;
        }
    
        public List<Entry> getEntryList2() {
            return entryList2;
        }
    }
    
    class Entry {
    
        private int id;
        private String type;
        private String property;
    
        public void setId(int id) {
            this.id = id;
        }
    
        public int getId() {
            return id;
        }
    
        public void setType(String type) {
            this.type = type;
        }
    
        public String getType() {
            return type;
        }
    
        public String getProperty() {
            return property;
        }
    
        public void setProperty(String property) {
            this.property = property;
        }
    
    }
    

    我使用这个问题的源代码编写了这个例子:

    【讨论】:

    • 谢谢 mykhaylo,我将使用您提供的解决方案,我不确定我是否完全理解的一个问题是为什么我需要在代码映射中提供“entry1List”和 2。put("entryList1 “, “顾客”);在我的代码中,我可以有 1..n 个条目列表,而不仅仅是一两个... mapping.put("entryList2", "Address");
    • 我不确定我是否理解您的问题。此映射定义应在 JSON 中更改哪些属性名称。如果您有超过 2 个属性,则应在此映射中定义所有属性
    • 您的意思是,例如 entityListContiner 可以与一个列表一起使用,并且每次我都会添加带有条目名称的新实例?我问这个是因为你在 entityListContiner 中硬编码了两个条目,entryList1@entryList2 但我可以得到很多条目列表...
    • 您可以根据需要构建任意数量的 Gson 类实例。您可以为每个实例配置不同的映射。例如,如果您有包含两个列表的类,则必须创建一个映射,如果您的类包含三个列表,则必须为其创建新的映射。请提供更好的解释您所拥有的以及您需要对所拥有的课程做些什么。我会尽力帮助你。
    • 谢谢 Michał,我想我需要尝试手动实现它,然后找到差距。再次感谢!
    【解决方案2】:

    因此您可以使用键作为实体/属性名称的映射(或嵌套映射)。然后将其转换为流

    Map data = new HashMap();
    List customerList = new ArrayList();
    Map customer = new HashMap();
    customer.put("id","00001");
    customer.put("type","USER");
    customerList.add(customer);
    
    //can create new customer and add to list
    data.put("customer",customerList);
    
    ObjectMapper mapper = new ObjectMapper();
    ByteArrayOutputStream out = new ByteArrayOutputStream();  
    
    //can save to file instead of printing using mapper.writeValue(file,data)
    
    mapper.writeValue(out, data);
    System.out.println(out.toString("UTF-8"));
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-10
      • 2014-12-08
      • 2011-03-10
      • 1970-01-01
      • 1970-01-01
      • 2012-04-23
      相关资源
      最近更新 更多