Je reçois une erreur en dessous:
Java.lang.ClassCastException: Java.util.LinkedHashMap cannot be cast to com.testing.models.Account
avec le code ci-dessous
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);
Y a-t-il une raison pour laquelle je ne peux pas faire get(0)
?
Le problème vient de Jackson. Lorsqu'il ne dispose pas de suffisamment d'informations sur la classe dans laquelle désérialiser, il utilise LinkedHashMap
.
Puisque vous n'informez pas Jackson du type d'élément de votre ArrayList
, il ne sait pas que vous souhaitez effectuer une désérialisation dans une ArrayList
de Account
s. Donc, il revient à la valeur par défaut.
Au lieu de cela, vous pourriez probablement utiliser as(JsonNode.class)
, puis traiter le ObjectMapper
de manière plus riche que ce que permet le repos assuré. Quelque chose comme ça:
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.readValue(
mapper.treeAsTokens(accounts),
new TypeReference<List<Account>>(){}
);
assertThat(accountList.get(0).getId()).isEqualTo(expectedId);
Essayez ce qui suit:
POJO pojo = mapper.convertValue(singleObject, POJO.class);
ou:
List<POJO> pojos = mapper.convertValue(
listOfObjects,
new TypeReference<List<POJO>>() { });
Voir conversion de LinkedHashMap pour plus d'informations.
La façon dont j'ai pu atténuer le tableau JSON à la collection d'objets LinkedHashMap problème a été d'utiliser CollectionType
plutôt qu'un TypeReference
. C'est ce que j'ai fait et travaillé :
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;
}
En utilisant TypeReference
, je continuais à obtenir une liste de tableaux de LinkedHashMaps, c.-à-d. ne fonctionne pas :
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;
}
J'ai eu une exception similaire (mais problème différent) - Java.lang.ClassCastException: Java.util.LinkedHashMap cannot be cast to org.bson.Document
, et heureusement, cela a été résolu plus facilement:
Au lieu de
List<Document> docs = obj.get("documents");
Document doc = docs.get(0)
qui donne une erreur en seconde ligne, on peut utiliser
List<Document> docs = obj.get("documents");
Document doc = new Document(docs.get(0));
J'ai cette méthode pour désérialiser un fichier XML et convertir le type:
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 );
}
et c'est l'appel:
List<POJO> pojos = (List<POJO>) MyUtilClass.deserialize(xml, ArrayList.class,new TypeReference< List< POJO >>(){ });