1

I need to create similar JSON file structure to the following post but its need to be dynamic, when I search I found the following post but the solution is specific for entry 1 and entry2 my needs is that the structure of the json will be exactly the same but can get any name of entity i.e. instead of entry the entity name could be customer,address ,sales order etc and then array with fields like key value .In the post the fields are hard-coded in the POJO'S but I need to provide ability to add any field to the entry ...there is a way to provide dynamic solution?

Thanks!

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",
                 ....
        }
    ]
}
Community
  • 1
  • 1
Jean Tennie
  • 253
  • 1
  • 5
  • 17

2 Answers2

2

You can use FieldNamingStrategy interface. It defines mapping between property name and name in JSON. Please, see my example:

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;
    }

}

I have written this example using source code from this question:

Community
  • 1
  • 1
Michał Ziober
  • 37,175
  • 18
  • 99
  • 146
  • Thanks mykhaylo ,I will use your provided solution,one question that im not sure that I fully understand is why do i need to provide "entry1List" and 2 also in the code mapping.put("entryList1", "customer"); in my code I can have 1..n entry list not just one or two... mapping.put("entryList2", "Address"); – Jean Tennie Jun 06 '13 at 10:36
  • I'm not sure that I understand your question. This mappings defines which property names should be changed in JSON. If you have more than 2 properties you should define all of it in this mapping – Michał Ziober Jun 06 '13 at 10:55
  • Do you mean for instance that the entityListContiner can be with one list and every time i will add new instance with the name of the entry? Im asking this since you hardcode in entityListContiner two entries,entryList1@entryList2 but I can get lot of entrylist's... – Jean Tennie Jun 06 '13 at 11:14
  • You can build so many instances of Gson class as you want. Each instance you can configure with different mappings. For example if you have class with two lists you have to create one mapping, if you have class with three lists you have to create new one for it. Please, provide better explanation what you have and what you need to do with classes which you have. I'll try to help you as best as I can. – Michał Ziober Jun 06 '13 at 11:22
  • Thanks Michał,I think I need to try to implement it manually and then find the gaps.Thanks again! – Jean Tennie Jun 06 '13 at 11:41
1

So you can have map (or nested maps) with keys as Entity/Attribute names. Then convert it to stream

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"));
Optional
  • 4,387
  • 4
  • 27
  • 45