Подтвердить что ты не робот

Java.lang.ClassCastException: java.util.LinkedHashMap не может быть добавлено в com.testing.models.Account

Я становлюсь ниже ошибки:

java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.testing.models.Account

с кодом ниже

final int expectedId = 1;

Test newTest = create();

int expectedResponseCode = Response.SC_OK;

ArrayList<Account> account = given().when().expect().statusCode(expectedResponseCode)
    .get("accounts/" + newTest.id() + "/users")
    .as(ArrayList.class);
assertThat(account.get(0).getId()).isEqualTo(expectedId);

Есть ли причина, по которой я не могу сделать get(0)?

4b9b3361

Ответ 1

Вопрос от Джексона. Когда у него недостаточно информации о том, какой класс десериализуется, он использует LinkedHashMap.

Поскольку вы не сообщаете Джексону о типе элемента вашего ArrayList, он не знает, что вы хотите десериализоваться в ArrayList из Account s. Таким образом, он возвращается к умолчанию.

Вместо этого вы, вероятно, можете использовать as(JsonNode.class), а затем справиться с ObjectMapper более богатым образом, чем разрешено в режиме ожидания. Что-то вроде этого:

ObjectMapper mapper = new ObjectMapper();

JsonNode accounts = given().when().expect().statusCode(expectedResponseCode)
    .get("accounts/" + newClub.getOwner().getCustId() + "/clubs")
    .as(JsonNode.class);


//Jackson use of generics here are completely unsafe, but that another issue
List<Account> accountList = mapper.readValue(
    mapper.treeAsTokens(accounts), 
    new TypeReference<List<Account>>(){}
);

assertThat(accountList.get(0).getId()).isEqualTo(expectedId);

Ответ 2

Попробуйте следующее:

POJO pojo = mapper.convertValue(singleObject, POJO.class);
// or:
List<POJO> pojos = mapper.convertValue(listOfObjects, new TypeReference<List<POJO>>() { });[conversion of Linkedhashmap][1]

Ответ 3

То, как я мог уменьшить массив JSON Array для коллекции объектов LinkedHashMap, состоял в использовании CollectionType, а не TypeReference. Это то, что я сделал и работал:

public <T> List<T> jsonArrayToObjectList(String json, Class<T> tClass) throws IOException {
    ObjectMapper mapper = new ObjectMapper();
    CollectionType listType = mapper.getTypeFactory().constructCollectionType(ArrayList.class, tClass);
    List<T> ts = mapper.readValue(json, listType);
    LOGGER.debug("class name: {}", ts.get(0).getClass().getName());
    return ts;
}

Используя TypeReference, я все еще получал ArrayList из LinkedHashMaps, т.е. не работает:

public <T> List<T> jsonArrayToObjectList(String json, Class<T> tClass) throws IOException {
    ObjectMapper mapper = new ObjectMapper();
    List<T> ts = mapper.readValue(json, new TypeReference<List<T>>(){});
    LOGGER.debug("class name: {}", ts.get(0).getClass().getName());
    return ts;
}

Ответ 4

У меня было подобное исключение (но другая проблема) - java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to org.bson.Document, и, к счастью, он решил легче:

Вместо

List<Document> docs = obj.get("documents");
Document doc = docs.get(0)

который дает ошибку во второй строке, можно использовать

List<Document> docs = obj.get("documents");
Document doc = new Document(docs.get(0));