Digamos que eu tenha um objeto java muito simples que tenha apenas algumas propriedades getXXX e setXXX. Este objeto é usado apenas para manipular valores, basicamente um registro ou um mapa de tipo seguro (e desempenho). Freqüentemente, preciso converter este objeto em pares de valores-chave (strings ou tipo seguro) ou converter pares de valores-chave para este objeto.
Além de reflexão ou escrever código manualmente para fazer essa conversão, qual é a melhor maneira de fazer isso?
Um exemplo pode ser o envio deste objeto por jms, sem usar o tipo ObjectMessage (ou converter uma mensagem recebida no tipo certo de objeto).
java
reflection
collections
javabeans
Shahbaz
fonte
fonte
java.beans.Introspector
.getBeanInfo()
. Ele está integrado ao JDK.Respostas:
Sempre há beanutils apache commons, mas é claro que ele usa reflexão sob o capô
fonte
java.beans
dependências severamente limitadas na plataforma. Veja a pergunta relacionada para detalhes.Muitas soluções potenciais, mas vamos adicionar apenas mais uma. Use Jackson (lib de processamento JSON) para fazer a conversão "json-less", como:
( esta entrada do blog tem mais alguns exemplos)
Basicamente, você pode converter qualquer tipo compatível: compatível, o que significa que se você converter de tipo para JSON e desse JSON para tipo de resultado, as entradas corresponderiam (se configuradas corretamente, também podem simplesmente ignorar as não reconhecidas).
Funciona bem para casos esperados, incluindo Maps, Lists, arrays, primitivos, POJOs semelhantes a bean.
fonte
BeanUtils
é bom, mas não pode lidar com matrizes e enumsA geração de código seria a única outra maneira que consigo pensar. Pessoalmente, eu consegui uma solução de reflexão geralmente reutilizável (a menos que essa parte do código seja absolutamente crítica para o desempenho). Usar JMS parece um exagero (dependência adicional, e nem mesmo é para isso que se destina). Além disso, provavelmente usa reflexão também sob o capô.
fonte
Este é um método para converter um objeto Java em um mapa
É assim que se chama
fonte
Provavelmente atrasado para a festa. Você pode usar Jackson e convertê-lo em um objeto Propriedades. Isso é adequado para classes aninhadas e se você quiser a chave para abc = value.
se você quiser algum sufixo, basta fazer
precisa adicionar esta dependência
fonte
Com o Java 8, você pode tentar isso:
fonte
JSON , por exemplo usando XStream + Jettison, é um formato de texto simples com pares de valores-chave. É suportado, por exemplo, pelo agente de mensagens Apache ActiveMQ JMS para troca de objetos Java com outras plataformas / linguagens.
fonte
Simplesmente usando reflexão e Groovy:
fonte
Use o BeanWrapper de juffrou- reflect. É muito performante.
Veja como você pode transformar um bean em um mapa:
Eu mesmo desenvolvi o Juffrou. É um código aberto, então você é livre para usá-lo e modificá-lo. E se você tiver alguma dúvida a respeito, terei o maior prazer em responder.
Felicidades
Carlos
fonte
Ao usar o Spring, também é possível usar o transformador objeto-para-mapa do Spring Integration. Provavelmente não vale a pena adicionar Spring como uma dependência apenas para isso.
Para obter a documentação, pesquise "Object-to-Map Transformer" em http://docs.spring.io/spring-integration/docs/4.0.4.RELEASE/reference/html/messaging-transformation-chapter.html
Essencialmente, ele percorre todo o gráfico do objeto acessível a partir do objeto fornecido como entrada e produz um mapa de todos os campos de tipo / String primitivos nos objetos. Ele pode ser configurado para produzir:
Aqui está um exemplo de sua página:
O resultado será:
Um transformador reverso também está disponível.
fonte
Você pode usar a estrutura Joda:
http://joda.sourceforge.net/
e aproveitar as vantagens do JodaProperties. Isso estipula que você crie beans de uma maneira particular e implemente uma interface específica. No entanto, ele permite que você retorne um mapa de propriedade de uma classe específica, sem reflexão. O código de amostra está aqui:
http://pbin.oogly.co.uk/listings/viewlistingdetail/0e78eb6c76d071b4e22bbcac748c57
fonte
Se você não deseja codificar chamadas para cada getter e setter, a reflexão é a única maneira de chamar esses métodos (mas não é difícil).
Você pode refatorar a classe em questão para usar um objeto Properties para conter os dados reais e permitir que cada getter e setter apenas chame get / set nele? Então você tem uma estrutura adequada para o que deseja fazer. Existem até métodos para salvá-los e carregá-los na forma de valor-chave.
fonte
A melhor solução é usar o Dozer. Você só precisa de algo assim no arquivo mapeador:
E é isso, Dozer cuida do resto !!!
URL de documentação Dozer
fonte
É claro que existe o meio mais simples de conversão possível - nenhuma conversão!
em vez de usar variáveis privadas definidas na classe, faça com que a classe contenha apenas um HashMap que armazena os valores da instância.
Em seguida, seus getters e setters retornam e configuram valores para dentro e para fora do HashMap e, quando é hora de convertê-lo em um mapa, voila! - já é um mapa.
Com um pouco de feitiçaria de AOP, você pode até manter a inflexibilidade inerente a um bean permitindo ainda usar getters e setters específicos para cada nome de valor, sem ter que realmente escrever os getters e setters individuais.
fonte
Você pode usar as propriedades do coletor de filtro de fluxo java 8,
fonte
Meu JavaDude Bean Annotation Processor gera código para fazer isso.
http://javadude.googlecode.com
Por exemplo:
O código acima gera a superclasse PersonGen que inclui um método createPropertyMap () que gera um Mapa para todas as propriedades definidas usando @Bean.
(Observe que estou mudando ligeiramente a API para a próxima versão - o atributo de anotação será defineCreatePropertyMap = true)
fonte
Você deve escrever um serviço de transformação genérico! Use genéricos para mantê-lo sem digitar (para que você possa converter todos os objetos em chave => valor e vice-versa).
Qual campo deve ser a chave? Obtenha esse campo do bean e acrescente qualquer outro valor não transitório em um mapa de valor.
O caminho de volta é bem fácil. Leia a chave (x) e escreva primeiro a chave e depois cada entrada da lista de volta para um novo objeto.
Você pode obter os nomes das propriedades de um bean com os beanutils do apache commons !
fonte
Se você realmente deseja desempenho, pode seguir a rota de geração de código.
Você pode fazer isso sozinho, fazendo sua própria reflexão e construindo um mixin AspectJ ITD.
Ou você pode usar Spring Roo e fazer um complemento Spring Roo . Seu complemento Roo fará algo semelhante ao acima, mas estará disponível para todos que usam Spring Roo e você não precisa usar Anotações de tempo de execução.
Eu fiz ambos. As pessoas fazem uma merda no Spring Roo, mas realmente é a geração de código mais abrangente para Java.
fonte
Uma outra maneira possível é aqui.
O BeanWrapper oferece funcionalidade para definir e obter valores de propriedade (individualmente ou em massa), obter descritores de propriedade e consultar propriedades para determinar se são legíveis ou graváveis.
fonte
Se se trata de uma árvore de objeto simples para o mapeamento da lista de valores-chave, em que a chave pode ser uma descrição de caminho pontilhada do elemento raiz do objeto para a folha sendo inspecionada, é bastante óbvio que uma conversão de árvore para uma lista de valores-chave é comparável a um mapeamento de objeto para xml. Cada elemento em um documento XML possui uma posição definida e pode ser convertido em um caminho. Portanto, usei o XStream como uma ferramenta de conversão básica e estável e substituí o driver hierárquico e as partes do gravador por uma implementação própria. O XStream também vem com um mecanismo básico de rastreamento de caminho que - sendo combinado com os outros dois - conduz estritamente a uma solução adequada para a tarefa.
fonte
Com a ajuda da biblioteca Jackson, consegui encontrar todas as propriedades da classe do tipo String / inteiro / duplo e respectivos valores em uma classe Map. ( sem usar reflexões api! )
fonte
Usando Gson,
object
em JsonConverter Json em mapa
fonte
Podemos usar a biblioteca Jackson para converter um objeto Java em um mapa facilmente.
Se estiver usando em um projeto Android, você pode adicionar jackson no build.gradle do seu aplicativo da seguinte maneira:
Implementação de amostra
Resultado:
{nome = XYZ, id = 1011, habilidades = [python, java]}
fonte