1

Here is a java class CreateDoc which is sent from One web service that is producer side to another web service which is consumer side as List with content-type:Json

Below is the class representation

class CreateDoc{
     DocMetData dMetaData;
     DocContent dCont;
}

Class DocMetData {
     String docNamel
     String docType;
}

Class DocContent {
     String data;
}

Once i receive the List as json in the consumer side i am not able to use this as a java Object and the content type is array with json nested inside an array.

Below is the Representation:

[  
   [  
      {  
         "dMetaData":{  
            "docName":"string",
            "docType":"pdf"
         },
         "dCont":{  
            "data":"abc"
         }
      },
      {  
         "dMetaData":{  
            "docName":"string",
            "docType":"pdf"

         },
         "dCont":{  
            "data":"def"
         }
      },
      {  
         "dMetaData":{  
            "docName":"string",
            "docType":"pdf"

         },
         "dCont":{  
            "data":"ghk"
         }
      }
   ]
]

Question is how to process this and be able to use the data and represent as List.

Prash
  • 544
  • 8
  • 24

4 Answers4

1

Here's some sample code that shows how you can use the Jackson ObjectMapper to parse the data. Note that the code assumes the data is stored in a file, you can modify it as needed to suit your needs.

Here's the main class:

package parsing.arrayofarray;

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;

import com.fasterxml.jackson.core.JsonParseException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.ObjectMapper;

public class ArrayOfArray {

    public static void main(String[] args) {
        ObjectMapper mapper = new ObjectMapper();
        String data = null;
        try {
            data = new String(Files.readAllBytes(Paths.get("src/main/resources/jsonArrayOfArray.json")));
        } catch (IOException e1) {
            e1.printStackTrace();
        }

        List<List<CreateDoc>> results = null;

        try {
            results = mapper.readValue(data, new TypeReference<List<List<CreateDoc>>>(){});
        } catch (JsonParseException e) {
            e.printStackTrace();
        } catch (JsonMappingException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }

        System.out.println(results);
    }

}

and here are the supporting classes, first CreateDoc:

package parsing.arrayofarray;

public class CreateDoc {
    DocMetData dMetaData;
    DocContent dCont;
    public DocMetData getdMetaData() {
        return dMetaData;
    }
    public void setdMetaData(DocMetData dMetaData) {
        this.dMetaData = dMetaData;
    }
    public DocContent getdCont() {
        return dCont;
    }
    public void setdCont(DocContent dCont) {
        this.dCont = dCont;
    }
    @Override
    public String toString() {
        return "CreateDoc [dMetaData=" + dMetaData + ", dCont=" + dCont + "]";
    }
}

and DocContent:

package parsing.arrayofarray;

public class DocContent {
    @Override
    public String toString() {
        return "DocContent [data=" + data + "]";
    }

    String data;

    public String getData() {
        return data;
    }

    public void setData(String data) {
        this.data = data;
    }
}

and the DocMetData:

package parsing.arrayofarray;

public class DocMetData {
    String docName;
    String docType;
    public String getDocNamel() {
        return docName;
    }
    public void setDocName(String docName) {
        this.docName = docName;
    }
    @Override
    public String toString() {
        return "DocMetData [docNamel=" + docName + ", docType=" + docType + "]";
    }
    public String getDocType() {
        return docType;
    }
    public void setDocType(String docType) {
        this.docType = docType;
    }
}

The output from the println is:

[[CreateDoc [dMetaData=DocMetData [docNamel=string, docType=pdf], dCont=DocContent [data=abc]], CreateDoc [dMetaData=DocMetData [docNamel=string, docType=pdf], dCont=DocContent [data=def]], CreateDoc [dMetaData=DocMetData [docNamel=string, docType=pdf], dCont=DocContent [data=ghk]]]]
D.B.
  • 4,523
  • 2
  • 19
  • 39
  • Compiler error at The method readValue(JsonParser, Class) in the type ObjectMapper is not applicable for the arguments (List, new TypeReference>>(){}) – Prash May 17 '18 at 20:26
  • Looks like you're passing the wrong parameters to the method. If you look carefully at the code I provided you will see I am passing the data as a `String`. The output of the method is a `List>` – D.B. May 17 '18 at 20:46
1

You can use JSONArray(org.json) to parse the first list, and parse with GSON the inside list to create a List of CreatDoc. You can use only GSON to parse the first array too

import java.util.ArrayList;
import java.util.List;

import org.json.JSONArray;

import com.google.common.reflect.TypeToken;
import com.google.gson.Gson;

public class Deserializer {

public static void main(String[] args) {
    JSONArray jsonArray = new JSONArray(
            "[[{\"dMetaData\": {\"docName\": \"string\",\"docType\": \"pdf\"},\"dCont\": {\"data\": \"abc\"}},{\"dMetaData\": {\"docName\": \"string\",\"docType\": \"pdf\"},\"dCont\": {\"data\": \"def\"}},{\"dMetaData\": {\"docName\": \"string\",\"docType\": \"pdf\"},\"dCont\": {\"data\": \"ghk\"}}]]");
    JSONArray docsArray = jsonArray.getJSONArray(0);
    List<CreateDoc> docsList = new Gson().fromJson(docsArray.toString(),
            new TypeToken<ArrayList<CreateDoc>>() {}.getType());
    docsList.forEach(System.out::println);
}

public static class CreateDoc {

    DocMetData dMetaData;
    DocContent dCont;

    @Override
    public String toString() {
        return this.dMetaData.toString() + " " + this.dCont.toString();
    }
}
public static class DocMetData {

    String docName;
    String docType;

    @Override
    public String toString() {
        return "name: " + this.docName + " type: " + this.docType;
    }
}
public static class DocContent {

    String data;

    @Override
    public String toString() {
        return "data: " + this.data;
    }
}

}

ghn1712
  • 105
  • 1
  • 3
  • 15
  • If there is more arrays inside the first array, you can use foreach and apply the same logic, that's more elegant and should be used instead of always use the first element – ghn1712 May 18 '18 at 19:24
-1

You can use GSON to parse the message into a JSONArray with JSONObjects. Then create a parser for each class to convert the fields from the JSONObject into Java objects. Similar question is anwered here.

AndrejH
  • 2,028
  • 1
  • 11
  • 23
  • Thanks but this is JSON encapsulated inside an array which is again nested. – Prash May 17 '18 at 19:52
  • You can parse the array and it will also parse all the nested parts. Take a look [here](https://stackoverflow.com/questions/18421674/using-gson-to-parse-a-json-array). – AndrejH May 17 '18 at 19:54
-1

I think the problem is you are trying to map json to CreateDoc instead of CreateDoc List. If you are using spring boot to manage rest layer in your application use @Requestbody List CreateDoc in the method to convert your json. This will use Jackson converter internally. Otherwise you can use Jackson converter jar to convert your json to objects.

Justin
  • 17
  • 4