8

Hey I have also problem here is my Json

[
{
    "aimid": "12345"
},
{
    "aimid": "333674"
},
{
    "aimid": [
        "4568999",
        "6789345"
    ]
}]

and This is my Pojo class:-

@JsonProperty("aimid")
private String aimid;


public String getAimid() {
    return aimid;
}

public void setAimid(String aimid) {
    this.aimid = aimid;
}

I want to store aimid in pojo . When i am writing like above in my application i am getting error.

com.fasterxml.jackson.databind.exc.MismatchedInputException: Cannot deserialize instance of `java.lang.String` out of START_ARRAY token.

From my understanding i am getting error because of Array element so anyone can suggest me how i can capture both thing if it is coming as String or It is coming as a Array String

Deepak Kumar
  • 83
  • 1
  • 1
  • 8
  • What exactly would you want as the resulting `aimid`, given that you receive an array with two different values? – Erich Kitzmueller Mar 04 '20 at 10:52
  • @ErichKitzmueller see i am consuming a rest Api in that all data is coming . So for capturing this data i created pojo class now in my api i am going to use this pojo . so what ever data is coming i need to capture and then i need to use. so whatever aimid is coming i need to capture.. – Deepak Kumar Mar 04 '20 at 10:58
  • your api data is not well-structured to do thing smoothly! You need to change your api response or you have to do some manual task if midification of api response is not possible – user404 Mar 04 '20 at 11:17
  • So can you tell me Where and how i can perform manually task because Response modification is not possible..@user404 – Deepak Kumar Apr 17 '20 at 08:28

1 Answers1

7

The challenge is that in some cases "aimid" is a string value but in another case it is an array.

If you have control over the structure of the JSON then update the structure so that each element of the root array has ONE of the following structures:

String { "aimid": "333674" } OR array { "aimid": [ "4568999", "6789345" ] }

If you do not have control of the structure of the data you will need to parse it yourself and process it into your POJO.

Please see these 3 code examples that should illustrate how you can go about this approaches. :

public class MyPojo {

    private List<String> aimid;

    @JsonProperty("aimid")
    public List<String> getAimid() {
    return aimid;
    }

    @JsonProperty("aimid_array")
    public void setAimid(final List<String> aimid) {
    this.aimid = aimid;
    }

    @JsonProperty("aimid")
    public void setAimid(final String aimid) {
    this.aimid = Arrays.asList(aimid);
    }
}


import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.node.*;
import java.io.IOException;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.junit.Test;

    public class UnitTest {

    private static final Logger LOGGER = Logger.getLogger(UnitTest.class.getName());

    public UnitTest() {
    }

    @Test
    public void testOneAimId() throws IOException {
    final String json = "[\n"
        + "{\n"
        + "    \"aimid\": \"12345\"\n"
        + "},\n"
        + "{\n"
        + "    \"aimid\": \"333674\"\n"
        + "}]";
    final List<MyPojo> result = new ObjectMapper().readValue(json, new TypeReference<List<MyPojo>>() {
    });
    log(Level.SEVERE, LOGGER, "testOneAimId", result);
    }

    @Test
    public void testListAimIds() throws IOException {
    final String json = "[\n"
        + "{\n"
        + "    \"aimid_array\": [\n" // HERE WE HAVE CHANGED THE JSON PROP NAME
        + "        \"4568999\",\n"
        + "        \"6789345\"\n"
        + "    ]\n"
        + "}]";
    final List<MyPojo> result = new ObjectMapper().readValue(json, new TypeReference<List<MyPojo>>() {
    });
    log(Level.SEVERE, LOGGER, "testListAimIds", result);
    }

    @Test
    public void testMixed() throws IOException {
    final String json = "[\n"
        + "{\n"
        + "    \"aimid\": \"12345\"\n"
        + "},\n"
        + "{\n"
        + "    \"aimid\": \"333674\"\n"
        + "},\n"
        + "{\n"
        + "    \"aimid_array\": [\n" // HERE WE HAVE CHANGED THE JSON PROP NAME
        + "        \"4568999\",\n"
        + "        \"6789345\"\n"
        + "    ]\n"
        + "}]";
    final List<MyPojo> result = new ObjectMapper().readValue(json, new TypeReference<List<MyPojo>>() {
    });
    log(Level.SEVERE, LOGGER, "testMixed", result);
    }

    @Test
    public void testMixed2() throws IOException {
    final String json = "[\n"
        + "{\n"
        + "    \"aimid\": \"12345\"\n"
        + "},\n"
        + "{\n"
        + "    \"aimid\": \"333674\"\n"
        + "},\n"
        + "{\n"
        + "    \"aimid\": [\n"
        + "        \"4568999\",\n"
        + "        \"6789345\"\n"
        + "    ]\n"
        + "}]";

    final JsonNode result = new ObjectMapper().readValue(json, JsonNode.class);
    final ArrayList<String> arrayList = new ArrayList<>();

    result.forEach((final JsonNode jsonNode) -> {

        if (jsonNode.getNodeType() != JsonNodeType.OBJECT)
        throw new IllegalArgumentException(jsonNode.toString());

        final ObjectNode obj = (ObjectNode) jsonNode;
        obj.forEach(o -> {
        switch (o.getNodeType()) {
            case ARRAY:
            final ArrayNode array = (ArrayNode) o;
            array.forEach(t -> arrayList.add(t.asText()));
            break;
            case STRING:
            arrayList.add(o.asText());
            break;
            default:
            throw new IllegalArgumentException(o.toString());
        }
        });
    });

    final MyPojo myPojo = new MyPojo();
    myPojo.setAimid(arrayList);
    log(Level.SEVERE, LOGGER, "myPojo", myPojo);
    }

    private void log(final Level level, final Logger logger, final String title, final Object obj) {
    try {
        if (title != null)
        logger.log(level, title);
        final ObjectWriter writer = new ObjectMapper().writerWithDefaultPrettyPrinter();
        logger.log(level, obj == null ? "null" : writer.writeValueAsString(obj));
    } catch (final JsonProcessingException ex) {
        logger.log(Level.SEVERE, ex.getMessage(), ex);
    }
    }
}
Jev Prentice
  • 129
  • 4
  • I think it will work let me implement It and Thank you so much for your response.. – Deepak Kumar Mar 06 '20 at 07:50
  • Thanks deepak there should be a an option below the up vote button (https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work) – Jev Prentice Mar 17 '20 at 07:10
  • 1
    Hey @Jev Prentice .. As u mentioned in solution @JsonProperty("aimid_array") but i have same name in both cases so how u wirtten as different what if i have same name with different Types.. – Deepak Kumar Apr 17 '20 at 06:32
  • Hi @DeepakKumar I think you may need to parse the json more manually (from a string) into a POJO, take a look at the example code in testMixed2() – Jev Prentice Apr 23 '20 at 10:26
  • Hey @Jev Prentice .. Few days back i am able to resolved that issues instead of defining type like Array and JSONArray we can assign read as Object then later we can Check the Instance of it and convert it in any form according to our requirement and set it in getMethod.... – Deepak Kumar Apr 24 '20 at 06:53