Following worked for me:

BaseResponse interface:
```
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = 
JsonTypeInfo.As.PROPERTY, visible = true, property = "isA")
@JsonSubTypes({
        @JsonSubTypes.Type(value = Customer.class, name = "Customer")})
public interface BaseResponse {
}
```

Customer class:
```
@Data
@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = 
JsonTypeInfo.As.PROPERTY, visible = true, property = "isA")
@JsonInclude(JsonInclude.Include.NON_NULL)
public class Customer implements BaseResponse {
    private String isA;
    private String name;
    private String age;
}
```

```
public class JacksonMain {
    public static void main(String[] args) throws IOException {
        final InputStream jsonStream = 
JacksonMain.class.getClassLoader().getResourceAsStream("Customer.json");
        final JsonParser jsonParser = new 
JsonFactory().createParser(jsonStream);
        final ObjectMapper objectMapper = new ObjectMapper();
        jsonParser.setCodec(objectMapper);

        //Goto the start of the document
        jsonParser.nextToken();

        try {
            BaseResponse baseResponse = objectMapper.readValue(jsonParser, 
BaseResponse.class);
            System.out.println("SINGLE EVENT INPUT");
            System.out.println(baseResponse.toString());
        } catch (Exception e) {
            System.out.println("LIST OF CUSTOMER INPUT");
            //Go until the customerList has been reached
            while (!jsonParser.getText().equals("customerList")) {
                jsonParser.nextToken();
            }
            jsonParser.nextToken();

            //Loop through each object within the customerList and 
deserilize them
            while (jsonParser.nextToken() != JsonToken.END_ARRAY) {
                final JsonNode customerNode = jsonParser.readValueAsTree();
                final String eventType = customerNode.get("isA").asText();
                Object event = objectMapper.treeToValue(customerNode, 
BaseResponse.class);
                System.out.println(event.toString());
            }
        }

    }
}
```

On Thursday, 2 September 2021 at 09:54:11 UTC+5:30 Aravinda Baliga B wrote:

> I am using the `Jackson` for the Deseilization of the JSON. The 
> `Deseilization` works perfectly for a JSON with `CustomerDocument`. 
> However, I have a new requirement in which I need to find whether provided 
> JSON has `CustomerDocument` or just `Customer`.
>
> I am able to develop the logic for both but the problem is that when I try 
> to merge it won't work for `CustomerDocument`. I am looking for a solution 
> that would work for both. All I would like to do is build the logic to 
> differentiate the incoming JSON based on `customerDocument` and single 
> `Customer`.
>
>
> Following is the `CustomerDocument` JSON:
> ```
> {
>   "isA": "CustomerDocument",
>   "customerList": [
>     {
>       "isA": "Customer",
>       "name": "Batman",
>       "age": "2008"
>     }
>   ]
> }
> ```
>
> Customer.class:
> ```
> @Data
> @JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = 
> JsonTypeInfo.As.PROPERTY, visible = true, property = "isA")
> @JsonInclude(JsonInclude.Include.NON_NULL)
> public class Customer {
>     private String isA;
>     private String name;
>     private String age;
> }
> ```
>
> JacksonMain:
> ```
> public class JacksonMain {
>     public static void main(String[] args) throws IOException {
>         final InputStream jsonStream = 
> JacksonMain.class.getClassLoader().getResourceAsStream("Customer.json");
>         final JsonParser jsonParser = new 
> JsonFactory().createParser(jsonStream);
>         final ObjectMapper objectMapper = new ObjectMapper();
>         jsonParser.setCodec(objectMapper);
>         
>         //Goto the start of the document
>         jsonParser.nextToken();
>         
>         //Go until the customerList has been reached
>         while (!jsonParser.getText().equals("customerList")) {
>             jsonParser.nextToken();
>         }
>         jsonParser.nextToken();
>
>         //Loop through each object within the customerList and deserilize 
> them
>         while (jsonParser.nextToken() != JsonToken.END_ARRAY) {
>             final JsonNode customerNode = jsonParser.readValueAsTree();
>             final String eventType = customerNode.get("isA").asText();
>             Object event = objectMapper.treeToValue(customerNode, 
> Customer.class);
>             System.out.println(event.toString());
>         }
>     }
> }
> ```
>
> The above code works perfectly and produces the following result:
> ```
> Customer(isA=Customer, name=Batman, age=2008)
> ```
>
> **Scenario-2**
>
> Now user can provide the direct `customer` object without the 
> `customerDocument`. Something like this:
> ```
> {
>   "isA": "Customer",
>   "name": "Superman",
>   "age": "2013"
> }
> ```
>
> 'Customer.class' would remain the same and `JacksonMain` would be modified 
> to:
> ```
> public class JacksonMain {
>     public static void main(String[] args) throws IOException {
>         final InputStream jsonStream = 
> JacksonMain.class.getClassLoader().getResourceAsStream("Customer.json");
>         final JsonParser jsonParser = new 
> JsonFactory().createParser(jsonStream);
>         final ObjectMapper objectMapper = new ObjectMapper();
>         jsonParser.setCodec(objectMapper);
>
>         //Goto the start of the document
>         jsonParser.nextToken();
>
>
>         final JsonNode jsonNode = jsonParser.readValueAsTree();
>         final String inputType = jsonNode.get("isA").asText();
>
>         if (inputType.equalsIgnoreCase("Customer")) {
>             Object singleCustomer = objectMapper.treeToValue(jsonNode, 
> Customer.class);
>             System.out.println(singleCustomer.toString());
>         } else if (inputType.equalsIgnoreCase("CustomerDocument")) {
>             //Go until the customerList has been reached
>             while (!jsonParser.getText().equals("customerList")) {
>                 jsonParser.nextToken();
>             }
>             jsonParser.nextToken();
>
>             //Loop through each object within the customerList and 
> deserilize them
>             while (jsonParser.nextToken() != JsonToken.END_ARRAY) {
>                 final JsonNode customerNode = jsonParser.readValueAsTree();
>                 final String eventType = customerNode.get("isA").asText();
>                 Object event = objectMapper.treeToValue(customerNode, 
> Customer.class);
>                 System.out.println(event.toString());
>             }
>         }
>     }
> }
> ```
>
> For a single `CUstomer` this would produce the following result:
> ```
> Customer(isA=Customer, name=Superman, age=2013)
> ```
>
> For the same code now if I provide the `CustomerDocument` (the first JSON) 
> then it would not work and fail with error:
> ```
> Exception in thread "main" java.lang.NullPointerException: Cannot invoke 
> "String.equals(Object)" because the return value of 
> "com.fasterxml.jackson.core.JsonParser.getText()" is null
> at stackover.JacksonMain.main(JacksonMain.java:32)
>
> ```
>
> I know this issue is happening because of the line 
> ```
> final JsonNode jsonNode = jsonParser.readValueAsTree();
> ```
>
> Can someone please explain how to make the code work for both the type of 
> JSON `customerDocument` and just single `Customer` using Jackson? I just 
> want to differentiate whether incoming JSON is `customerDocument` or single 
> `Customer`. Any help would be really appreciated.
>

-- 
You received this message because you are subscribed to the Google Groups 
"jackson-user" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/jackson-user/a7c05d8f-73fb-46e1-98f0-c5ac934bd001n%40googlegroups.com.

Reply via email to