Eu tenho uma string json, que eu devo desserializar para a seguinte classe
class Data <T> {
int found;
Class<T> hits
}
Como eu faço isso? Esta é a maneira usual
mapper.readValue(jsonString, Data.class);
Mas como menciono o que T significa?
Respostas:
Você precisa criar um
TypeReference
objeto para cada tipo genérico que você usar e usar isso para desserialização. Por exemplo -fonte
Data<T>
, esse NÃO é um tipo. Você deve especificar a classe real; caso contrário, é o mesmo queData<Object>
.TypeReference
? é issocom.fasterxml.jackson.core.type
?Você não pode fazer isso: você deve especificar o tipo totalmente resolvido, como
Data<MyType>
.T
é apenas uma variável e, como não tem sentido.Mas se você quer dizer que
T
isso será conhecido, apenas não estaticamente, você precisará criar o equivalenteTypeReference
dinamicamente. Outras perguntas mencionadas já podem mencionar isso, mas deve ser algo como:fonte
TypeReference
:return mapper.readValue(json, clazz);
Qual é exatamente o problema aqui?TypeFactory
.. Vou editar minha resposta.A primeira coisa que você faz é serializar, depois pode desserializar.
portanto, ao serializar, você deve
@JsonTypeInfo
permitir que jackson escreva informações de classe em seus dados json. O que você pode fazer é assim:Então, quando você desserializar, você descobrirá que jackson desserializou seus dados em uma classe na qual suas ocorrências variáveis realmente estão no tempo de execução.
fonte
Para a classe Data <>
fonte
Basta escrever um método estático na classe Util. Estou lendo um Json de um arquivo. você pode dar String também para readValue
Uso:
fonte
Você pode agrupá-lo em outra classe que sabe o tipo do seu tipo genérico.
Por exemplo,
Aqui, algo é do tipo concreto. Você precisa de um invólucro por tipo reificado. Caso contrário, Jackson não sabe quais objetos criar.
fonte
A sequência JSON que precisa ser desserializada precisará conter as informações de tipo sobre o parâmetro
T
.Você precisará colocar anotações de Jackson em todas as classes que podem ser passadas como parâmetro
T
para classe,Data
para que as informações sobre o tipo de parâmetroT
possam ser lidas / gravadas na string JSON por Jackson.Vamos supor que
T
possa ser qualquer classe que estenda a classe abstrataResult
.Depois que cada classe (ou seu supertipo comum) que pode ser passado como parâmetro
T
for anotado, Jackson incluirá informações sobre o parâmetroT
no JSON. Esse JSON pode então ser desserializado sem conhecer o parâmetroT
no tempo de compilação.Este link da documentação de Jackson fala sobre desserialização polimórfica, mas também é útil para se referir a essa pergunta.
fonte
No Jackson 2.5, uma maneira elegante de resolver isso é usar o método TypeFactory.constructParametricType (Classe parametrizada, Classe ... parameterClasses) que permite definir diretamente um Jackson
JavaType
especificando a classe parametrizada e seus tipos parametrizados.Supondo que você deseja desserializar
Data<String>
, você pode:Observe que se a classe declarasse vários tipos com parâmetros, não seria muito mais difícil:
Nós poderíamos fazer :
fonte
fonte
se você estiver usando scala e souber o tipo genérico em tempo de compilação, mas não quiser passar manualmente TypeReference em todos os lugares em todos os seus aplicativos API, poderá usar o seguinte código (com jackson 2.9.5):
que pode ser usado assim:
fonte
Para desserializar uma string JSON genérica para um objeto Java com Jackson, você precisa:
Para definir uma classe JSON.
Execute um mapeamento de atributos.
Código final, testado e pronto para ser usado:
Importante: a
@JsonAnySetter
anotação é obrigatória, assegura uma análise e uma população JSON genéricas.Para casos mais complicados com matrizes aninhadas, consulte a referência da Baeldung: https://www.baeldung.com/jackson-mapping-dynamic-object
fonte
Exemplo de decisão não muito boa, mas simples (não apenas para Jackson, também para Spring RestTemplate, etc.):
fonte