J'ai une chaîne json, que je devrais désérialiser dans la classe suivante
class Data <T> {
int found;
Class<T> hits
}
Comment fait-on ça? C'est la manière habituelle
mapper.readValue(jsonString, Data.class);
Mais comment mentionner ce que signifie T?
Réponses:
Vous devez créer un
TypeReference
objet pour chaque type générique que vous utilisez et l'utiliser pour la désérialisation. Par exemple -la source
Data<T>
, ce n'est PAS un type. Vous devez spécifier la classe réelle; sinon c'est la même chose queData<Object>
.TypeReference
? c'est çacom.fasterxml.jackson.core.type
?Vous ne pouvez pas faire cela: vous devez spécifier un type entièrement résolu, comme
Data<MyType>
.T
est juste une variable, et comme cela n'a pas de sens.Mais si vous voulez dire que
T
cela sera connu, mais pas de manière statique, vous devez créer l'équivalent deTypeReference
dynamiquement. D'autres questions référencées peuvent déjà le mentionner, mais cela devrait ressembler à quelque chose comme:la source
TypeReference
:return mapper.readValue(json, clazz);
Quel est exactement le problème ici?TypeFactory
.. Je modifierai ma réponse.La première chose à faire est de sérialiser, puis de désérialiser.
Ainsi, lorsque vous sérialisez, vous devez utiliser
@JsonTypeInfo
pour laisser jackson écrire les informations de classe dans vos données json. Voici ce que vous pouvez faire:Ensuite, lorsque vous désérialisez, vous constaterez que jackson a désérialisé vos données dans une classe que votre variable atteint réellement lors de l'exécution.
la source
Pour les données de classe <>
la source
Écrivez simplement une méthode statique dans la classe Util. Je lis un Json à partir d'un fichier. vous pouvez également donner String à readValue
Usage:
la source
Vous pouvez l'envelopper dans une autre classe qui connaît le type de votre type générique.
Par exemple,
Ici, quelque chose est un type concret. Vous avez besoin d'un wrapper par type réifié. Sinon, Jackson ne sait pas quels objets créer.
la source
La chaîne JSON qui doit être désérialisée devra contenir les informations de type sur le paramètre
T
.Vous devrez mettre des annotations Jackson sur chaque classe qui peut être transmise en tant que paramètre
T
à la classeData
afin que les informations de type sur le type de paramètreT
puissent être lues / écrites dans la chaîne JSON par Jackson.Supposons que cela
T
puisse être n'importe quelle classe qui étend une classe abstraiteResult
.Une fois que chacune des classes (ou leur supertype commun) qui peut être transmise en tant que paramètre
T
est annotée, Jackson inclura des informations sur le paramètreT
dans le JSON. Un tel JSON peut ensuite être désérialisé sans connaître le paramètreT
au moment de la compilation.Ce lien de documentation Jackson parle de la désérialisation polymorphe, mais il est également utile de s'y référer pour cette question.
la source
Depuis Jackson 2.5, une manière élégante de résoudre cela utilise la méthode TypeFactory.constructParametricType (Class parametrized, Class ... parameterClasses) qui permet de définir directement un Jackson
JavaType
en spécifiant la classe paramétrée et ses types paramétrés.En supposant que vous souhaitiez désérialiser vers
Data<String>
, vous pouvez faire:Notez que si la classe déclarait plusieurs types paramétrés, ce ne serait pas vraiment plus difficile:
Nous pourrions faire :
la source
la source
si vous utilisez scala et connaissez le type générique au moment de la compilation, mais que vous ne voulez pas passer manuellement TypeReference partout dans tous vos api l ayers, vous pouvez utiliser le code suivant (avec jackson 2.9.5):
qui peut être utilisé comme ceci:
la source
Pour désérialiser une chaîne JSON générique en objet Java avec Jackson, vous avez besoin de:
Pour définir une classe JSON.
Effectuez un mappage d'attributs.
Code final, testé et prêt à être utilisé:
Important: l'
@JsonAnySetter
annotation est obligatoire, elle garantit une analyse et un peuplement JSON génériques.Pour les cas plus compliqués avec des tableaux imbriqués, veuillez consulter la référence Baeldung: https://www.baeldung.com/jackson-mapping-dynamic-object
la source
Exemple de décision pas très bonne, mais simple (pas seulement pour Jackson, également pour Spring RestTemplate, etc.):
la source