Ошибка Джексона: Невозможно десериализовать экземпляр `java .lang.String` из токена START_ARRAY - PullRequest
1 голос
/ 04 марта 2020

Эй, у меня тоже проблема, вот мой Json

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

и это мой класс Pojo: -

@JsonProperty("aimid")
private String aimid;


public String getAimid() {
    return aimid;
}

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

Я хочу сохранить aimid в pojo. Когда я пишу в приложении, как указано выше, я получаю сообщение об ошибке.

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

Из моего понимания я получаю сообщение об ошибке из-за элемента массива, поэтому любой может подсказать мне, как я могу запечатлеть обе вещи, если они поступают как Строка или это как массив строк

1 Ответ

1 голос
/ 04 марта 2020

Сложность заключается в том, что в некоторых случаях «aimid» является строковым значением, а в другом случае - массивом.

Если вы контролируете структуру JSON, обновите структуру так, чтобы Каждый элемент массива root имеет одну из следующих структур:

String {"aimid": "333674"} ИЛИ массив {"aimid": ["4568999", "6789345"]}

Если у вас нет контроля над структурой данных, вам нужно будет проанализировать их самостоятельно и обработать в POJO.

Пожалуйста, посмотрите эти 3 примера кода, которые должны проиллюстрировать, как вы можете go об этом подходит. :

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