Pergunta

Para contexto, estamos armazenando a maioria dos nossos dados como strings JSON. Isso funciona muito bem com Hadoop no backend e é fácil de manusear em Ruby na extremidade dianteira. Meus tipos de dados se encaixam no padrão natural para herança.

Para simplificar, digamos que eu tenho uma classe animal de estimação e um processo FeedPet que alimenta um animal de estimação. Eu também tenho um processo WalkDog que só se aplica a Dog, que é um tipo de animal de estimação. Meus dados está organizado de tal forma que eu nunca precisa se preocupar em tentar andar um animal de estimação que não é um cão.

O que eu gostaria de fazer é ter Pet and Dog estende Pet, com Cão que tem um método adicional "getLeash ()", mas eu não consigo descobrir como mapear isso para JSON.

Em vez disso, eu tenho uma classe animal de estimação com um hashmap dados de espécies, de modo que o processo de WalkDog chamaria pet.getSpeciesData ( "coleira") em vez de dog.getLeash ().

Eu posso criar um cão estende Pet, e posso serializar que para JSON usando a biblioteca Jackson. O objeto JSON terá um campo trela. Mas suponha que eu quero alimentar todos os animais de estimação. Todos os animais de estimação têm um método getFood (). Assim, o processo FeedPet desserializa os objetos para Pet. Mas isso perde o campo trela.

O processo WalkDog pode fazer isso porque ele sabe tudo de sua entrada vai ser Dogs, para que ele possa lê-lo como um cão e escrevê-lo de volta como um cão.

Existe alguma maneira de objetos serialize Java para JSON de modo que eu possa preservar o seu tipo? Estou pensando em algo como Rails herança única tabela, mas teria que ser algo que as bibliotecas JSON entender.

Foi útil?

Solução

Para fazer o trabalho você deve ambos incorporar algumas informações tipo de objeto em dados (onde só é útil para desserialização) e, geralmente, usar a definição esquema externo que de outra forma não seria necessário (como XML Schema para XML, uma vez que é basicamente um genérico sistema de tipo). Isto tem mesmos problemas que ORM tem:. Hibernate tem que usar soluções alternativas feias (n + 1 - caminho junta-se, de "super mesas" ou campos discriminadores)

Ou uma outra maneira de colocá-lo:. Mapeamento de dados / ligação não é exatamente o mesmo que objeto de serialização / desserialização (últimas tentativas para preservar mais de identidade de objeto)

Aqui eu estou supondo que o que você quer é basicamente algo como:

Pet pet = mapper.readValue(jsonString, Pet.class);
// (and possibly get an exception if Pet is an abstract class...)
Leash l = ((Dog) pet).getLeash();

Se isto não for o caso, você pode simplesmente ligar a Dog

Dog dog = mapper.readValue(jsonString, Dog.class);

De qualquer forma: Projeto Jackson tem pedido de recurso para fazer exatamente isso , que permitem -lo a fazer o que (eu acho) que você deseja.

No entanto, esta solução vai trabalhar principalmente para Java, como não há nenhuma maneira padrão de passar informações tipo de objeto dentro JSON. Com XML isso pode classificar de ser feito com XML Schema definido: atributo "xsi tipo"; que identifica o tipo de esquema, que é então mapeado para classe (sim, forma bastante complicado, mas ela não funciona).

Atualizar : Jackson 1.5 suporte adicional para este (ou seja implementado JACKSON -91 pedido de recurso), por isso pode ser usado para gerar identificadores do tipo, para permitir a manipulação adequada de tipos polimórficos. Ele deve funcionar com os sistemas não-Java também, já que você pode detalhes totalmente configure de como informações de tipo deve ser incluído; e não é limitado a usar nomes de classe Java.

Outras dicas

Eu não tive muita experiência usando JSON excepto para luminárias em Django, mas nesse caso eu só tenho uma chave "modelo", com o valor associado.

Cabe então ao programa que está a interpretar os objetos para determinar o seu tipo de hierarquia e herança.

O que eu estou tentando dizer é que é irrelevante que métodos estão disponíveis, já que este não precisa ser serializado. Somente o nome e os atributos do objeto.

- atualização

Depois de ler a sua pergunta novamente, parece que o processo está deserialising na classe pai, ao invés da classe real. Desde seus herda classe cão de estimação, você só quer se certificar que sua deserialiser está criando objetos da classe mais especializada.

Eu não sei sobre a biblioteca de Jackson, mas se você pode configurá-lo para ter um tipo de campo de modelo, em seguida, que pode ser qualquer lugar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top