0

I am trying to unmarshal the following JSON

[{
    "myId": "12851cb3087f51b4fb392b1fea36eef9508",
    "secondaryId": "787CFD4A-6B1D-4415-AD56-D075B535B890",
    "my_key": "keyABCD",
    "email": ""
}, {
    "myId": "12851cb3087f51b4fb392b1fea36eef9508",
    "secondaryId": "BFACD2F0-F5EF-4F05-AA6B-00E18CA907EF",
    "my_key": "keyABCD",
    "email": ""
}, {
    "myId": "12851cb3087f51b4fb392b1fea36eef9508",
    "secondaryId": "567DE8C0-B5B5-4961-B97A-A2DD374AEED1",
    "my_key": "keyABCD",
    "email": ""
}, {
    "myId": "12851cb3087f51b4fb392b1fea36eef9508",
    "secondaryId": "78a52d90-be6c-4d80-b79d-0e256028ba01",
    "my_key": "keyABCD",
    "email": "test@email.com"
}, {
    "myId": "12851cb3087f51b4fb392b1fea36eef9508",
    "secondaryId": "aeb148e7-fc88-4a71-8baa-63b6528e463e",
    "my_key": "keyABCD",
    "email": ""
}]

and already have a bufferreader (myBufferedReader) which has the above json. POJO

import lombok.AllArgsConstructor;
import lombok.Getter;
import lombok.Setter;
import lombok.ToString;

@ToString
@AllArgsConstructor
public class MyPOJO {
    @Getter @Setter private String myId;
    @Getter @Setter private String secondaryId;
    @Getter @Setter private String my_key;
    @Getter @Setter private String email;

}

On using below mapper -

ObjectMapper mapper = new ObjectMapper();
List<MyPOJO> eventList = mapper.readValue(myBufferedReader.readLine(),mapper.getTypeFactory().constructCollectionType(List.class, MyPOJO.class));

getting error. Please help. - (no Creators, like default construct, exist): cannot deserialize from Object value (no delegate- or property-based Creator)

If above is not the correct way, please suggest the best way to read from bufferreader and create list of pojo class mapped with json.

Regards, Dan

TechDan
  • 37
  • 5
  • I have posted an answer that uses the library `javax.json.*`... It does not use `lombok`. I can see what `lombok` does, but I don't know how much **JSON** you intend to use. Automatically building Java POJO's seems like complete over-kill, but I am not an expert in **JSON + Java**. This linked answer (below) discusses using `lombok` to convert **JSON** to a **`POJO`** - although I see that your problem is that you have a `JsonArray` with several instances of the **POJO** to parse... [Lombok Answer](https://stackoverflow.com/questions/49999492/immutable-lombok-annotated-class-with-jackson) – Y2020-09 Oct 08 '20 at 02:29
  • Here are some answers that claim you need `Lombok` and the `Jackson` **JSON Parser** - _which is a different **JSON Parser**_. I truly believe, that this type of stuff is **only valuable** if you have many **JSON `String's`** to parse, and many different types of `Object's`... [JSON Array](https://stackoverflow.com/questions/62195156/mapping-a-json-array-to-pojo-using-lombok), [Lombok + Jackson JsonArray](https://stackoverflow.com/questions/60311290/lombok-jackson-pojo-for-a-json-array) – Y2020-09 Oct 08 '20 at 02:36
  • add `@NoArgConstructor` top of your class too – user404 Oct 08 '20 at 04:36

2 Answers2

1

Well, I am not a Master of all things Java JSON. I have a tool which I use whenever I need to parse JSON. Be aware that there are multiple tools for parsing JSON String's, but I am only going to post the solution for the version that I use. I, personally, do not get into Java's Component Annotations because they add such a tremendous amount of complexity, and do not add anything to value of the code. I am not here to prove my points, but I don't get into Java Beans.

There is a library called the GSON Library that (supposedly) can map JSON String's directly to Java Object's (POJO's as you called them). I am, unfortunately, unfamiliar with the GSON Tool, and it might actually be able to "automatically" build a class MyPOJO using Annotations as you have requested.

Here is my solution, which just uses the standard JSON Parsing Library which I call javax.json.* below. You would have to retrieve the JSON JAR by looking for it using a Google Search.

import java.io.*;
import javax.json.*;

public class S
{
    // I am just going to create the class for parsing this
    // If there is a GSON way to do this "Automatically", then you
    // should not use this Answer I have written to Stack Overflow

    public static class MyPOJO
    {
        public final String myId;
        public final String secondaryId;
        public final String myKey;
        public final String email;

        public MyPOJO(String myId, String secondaryId, String myKey, String email)
        { this.myId=myId; this.secondaryId=secondaryId; this.myKey=myKey; this.email=email; }

        public String toString()
        {
            return
                "myId:         " + myId         + '\n' +
                "seoondaryId:  " + secondaryId  + '\n' +
                "myKey:        " + myKey        + '\n' +
                "email:        " + email        + "\n\n";
        }
    }

    public static void main(String[] argv) throws IOException
    {
        // This reads the 'input.json' file into the Json parser using
        // a simple java.io.FileReader
        Reader r = new FileReader("input.json");

        // This reads the file, and retrieves the JsonArray that you
        // have provided in your original post.
        JsonArray ja = Json
            .createReader(r)
            .readArray();
        
        for (JsonObject jo : ja.getValuesAs(JsonObject.class))
        {
            String myId         = jo.getString("myId");
            String secondaryId  = jo.getString("secondaryId");
            String myKey        = jo.getString("my_key");
            String email        = jo.getString("email");

            // What *I* would do is to get rid of the Component Annotation, and simply 
            // use a Constructor.  I don't strongly believe in Java's Annotation Classes,
            // and I never use them.  If you can find an AUTOMATED WAY to do all of this,
            // YOU SHOULD ... - if you are willing to learn it all.
            // I HAVE NOT! :)
            
            // If there is an easy way to **DIRECTLY MAP** a JSON Object to a specified
            // class - and I believe that the GSON library is capable of directly mapping
            // JSON Object's to GSON Java POJO's (Java Object's), but I have not used them
            // before.  My own personal belief is that if it were easier, then learning the
            // GSON JAR Library and Java Documentation (JavaDoc) for GSON.

            // Here, though, a Constructor is what I would prefer myself.
            MyPOJO mp = new MyPOJO(myId, secondaryId, myKey, email);
            System.out.println(mp.toString());
        }
    }
}

The following is output by the above class to the Shell Terminal:

@cloudshell:~$ java S
myId:         12851cb3087f51b4fb392b1fea36eef9508
seoondaryId:  787CFD4A-6B1D-4415-AD56-D075B535B890
myKey:        keyABCD
email:        


myId:         12851cb3087f51b4fb392b1fea36eef9508
seoondaryId:  BFACD2F0-F5EF-4F05-AA6B-00E18CA907EF
myKey:        keyABCD
email:        


myId:         12851cb3087f51b4fb392b1fea36eef9508
seoondaryId:  567DE8C0-B5B5-4961-B97A-A2DD374AEED1
myKey:        keyABCD
email:        


myId:         12851cb3087f51b4fb392b1fea36eef9508
seoondaryId:  78a52d90-be6c-4d80-b79d-0e256028ba01
myKey:        keyABCD
email:        test@email.com


myId:         12851cb3087f51b4fb392b1fea36eef9508
seoondaryId:  aeb148e7-fc88-4a71-8baa-63b6528e463e
myKey:        keyABCD
email:        
Y2020-09
  • 1
  • 5
1

Add your default constructor, empty constructor, by adding @NoArgConstructor top of your POJO class. Then simply convert your buffer reader JSON string to a list of POJO like this:

List<MyPOJO> eventList = mapper.readValue(myBufferedReader, new TypeReference<List<MyPOJO>>(){});
user404
  • 1,934
  • 1
  • 16
  • 32