java.lang.ClassCastException: java.util.LinkedHashMap kann nicht in com.testing.models.Account umgewandelt werden

Lesezeit: 6 Minuten

Benutzer-Avatar
Leidenschaftlicher Ingenieur

Ich bekomme folgenden Fehler:

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

mit untenstehendem Code

final int expectedId = 1;

Test newTest = create();

int expectedResponseCode = Response.SC_OK;

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

Gibt es einen Grund, warum ich das nicht kann get(0)?

  • Kann nicht gecastet werden was? Wie lautet der Rest der Fehlermeldung?

    – Oliver Charlesworth

    3. März 2015 um 0:02 Uhr

  • @OliverCharlesworth hat auch den gesamten Stacktrace hinzugefügt

    – Leidenschaftlicher Ingenieur

    3. März 2015 um 0:05 Uhr

  • Was ist ein Account? Warum versuchst du, von einer Karte darauf zu werfen?

    – David Newton

    3. März 2015 um 0:06 Uhr

  • Können Sie für diejenigen von uns, die mit der Bibliothek nicht vertraut sind, sagen, welche Klasse das ist? given() Methode wird statisch importiert?

    – Markus Peters

    3. März 2015 um 0:07 Uhr

  • @DaveNewton Account ist ein Modell von Dropwizard, das verwendet com.fasterxml.jackson.databind.annotations

    – Leidenschaftlicher Ingenieur

    3. März 2015 um 0:08 Uhr

Benutzer-Avatar
Markus Peters

Das Problem kommt von Jackson. Wenn es nicht genügend Informationen darüber hat, in welche Klasse es deserialisiert werden soll, verwendet es LinkedHashMap.

Da Sie Jackson nicht über den Elementtyp Ihrer informieren ArrayListweiß es nicht, dass Sie in ein deserialisieren möchten ArrayList von Accounts. Es fällt also auf die Voreinstellung zurück.

Stattdessen könnten Sie wahrscheinlich verwenden as(JsonNode.class)und beschäftigen Sie sich dann mit der ObjectMapper auf reichere Art und Weise, als es die Zuversicht zulässt. Etwas wie das:

ObjectMapper mapper = new ObjectMapper();

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


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

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

  • Sie können die Antwort auch als String () festlegen, was zusätzliche Konvertierungen erspart – readValue akzeptiert einen String als erstes Argument.

    – BIGDeutsch

    9. Juni 2016 um 9:25 Uhr

  • @BIGDeutsch: Wenn ich das nur noch einmal durchgehe, war es nicht nötig, dass ich dort wieder in Token umwandelte convertValue könnte es in einem Schritt tun. Zu einer Zeichenfolge zu gehen funktioniert auch.

    – Markus Peters

    6. März 2019 um 17:07 Uhr

  • was zu tun ist, wenn ein Objekt eine Variable enthält, die list ist. Wie deserialisiert man das Objekt mit Jackson?

    – Benutzer1887464

    9. Oktober 2021 um 12:29 Uhr

  • sehr hilfreich, danke

    – danisupr4

    10. Februar um 19:16 Uhr

Benutzer-Avatar
Benutzer2578871

Versuche Folgendes:

POJO pojo = mapper.convertValue(singleObject, POJO.class);

oder:

List<POJO> pojos = mapper.convertValue(
    listOfObjects,
    new TypeReference<List<POJO>>() { });

Weitere Informationen finden Sie unter Konvertierung von LinkedHashMap.

  • +1 für das Anzeigen von “convertValue”. Ich hatte einen Fall, in dem ich eine bestimmte Eigenschaft aus json als Liste auslesen musste, und das ist genau das, was ich brauchte.

    – GameSalutes

    20. Juni 2017 um 21:02 Uhr

So konnte ich das abmildern JSON-Array zur Sammlung von LinkedHashMap-Objekten Problem war durch die Verwendung CollectionType eher als ein TypeReference . Das habe ich getan und hat funktioniert:

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

Verwendung der TypeReferenceich bekam immer noch eine ArrayList von LinkedHashMaps, dh funktioniert nicht:

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

  • Hat mein Problem auch gespeichert. Vielen Dank!

    – Wladimir Gilewitsch

    5. Oktober 2017 um 14:53 Uhr

  • +1, der Unterschied in Ihrem Fall war, dass die Methode selbst so generisch war T konnte nicht über das TypeToken verifiziert werden, was normalerweise einfacher ist. Persönlich bevorzuge ich den Helfer von Guava, weil er immer noch typsicher und nicht spezifisch für einen Containertyp ist: return new TypeToken<List<T>>(){}.where(new TypeParameter<T>(){}, tClass). Aber Jackson nimmt nicht TypeTokens so brauchen Sie dann .getType().

    – Markus Peters

    24. November 2017 um 15:22 Uhr


  • Hat mein Problem auch gespeichert. Vielen Dank!

    – Schaschenk

    17. Juli 2020 um 3:32 Uhr

  • Vielen Dank! Ich habe viel Zeit damit verbracht, diesen Fehler zu beheben, bis ich diese Antwort gefunden habe !!

    – glco

    8. Dezember 2020 um 18:33 Uhr

  • Schön!!. Das hat mir auch den Tag gerettet 🙂 .. Ich habe stundenlang gekämpft, bevor ich diese Lösung gefunden habe. Ich habe versucht, einen generischen JSONB-Array-Konverter für JOOQ in Kotlin zu schreiben.

    – sumanr

    23. Februar 2021 um 12:45 Uhr

Benutzer-Avatar
nurb

Ich hatte eine ähnliche Ausnahme (aber ein anderes Problem) – java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to org.bson.Document und zum Glück ist es einfacher zu lösen:

Anstatt von

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

was einen Fehler in der zweiten Zeile gibt, kann man verwenden

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

Lösen Sie das Problem mit zwei Methoden parse common

  1. Der Typ ist ein Objekt
public <T> T jsonToObject(String json, Class<T> type) {
        T target = null;
        try {
            target = objectMapper.readValue(json, type);
        } catch (Jsenter code hereonProcessingException e) {
            e.printStackTrace();
        }
    
        return target;
    }
  1. With type ist ein Collection-Wrap-Objekt
public <T> T jsonToObject(String json, TypeReference<T> type) {
    T target = null;
    try {
        target = objectMapper.readValue(json, type);
    } catch (JsonProcessingException e) {
        e.printStackTrace();
    }
    return target;
}

Benutzer-Avatar
siddharth jain

Dies ist etwas, das ich in meinem Projekt verwendet habe, Json-Objekt wurde zurückgegeben, ich habe es in eine Liste von POJO, List konvertiert und dann auf das Element zugegriffen. Ich habe die Eingabe des Json-Objekts von einem anderen Microservice übernommen.

Hauptsache: –
JsonNode stocks = restTemplate.getForObject(“http://localhost:2000/stocks/qty”, JsonNode.class); List stockList = mapper.convertValue(stocks, new TypeReference>() {});

@GetMapping("/")
    public List<Stock_id_qty> checkQty() throws JsonProcessingException {
        ObjectMapper mapper = new ObjectMapper();
        JsonNode stocks = restTemplate.getForObject("http://localhost:2000/stocks/qty", JsonNode.class);
        List<Stock_id_qty> stockList = mapper.convertValue(stocks, new TypeReference<List<Stock_id_qty>>() {});
        List<Stock_id_qty> result = new ArrayList<>();
        for(Stock_id_qty s : stockList){
            if(s.getStockQty() < 10)
            {
                result.add(s);
            }
        }
        return result;
    }

Benutzer-Avatar
Ishaan Javali

Ich habe diese Methode zum Deserialisieren eines XML und Konvertieren des Typs:

public <T> Object deserialize(String xml, Class objClass ,TypeReference<T> typeReference ) throws IOException {
    XmlMapper xmlMapper = new XmlMapper();
    Object obj = xmlMapper.readValue(xml,objClass);
    return  xmlMapper.convertValue(obj,typeReference );   
}

und das ist der Aufruf:

List<POJO> pojos = (List<POJO>) MyUtilClass.deserialize(xml, ArrayList.class,new TypeReference< List< POJO >>(){ });

1299250cookie-checkjava.lang.ClassCastException: java.util.LinkedHashMap kann nicht in com.testing.models.Account umgewandelt werden

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy