Digamos que tengo un objeto java muy simple que solo tiene algunas propiedades getXXX y setXXX. Este objeto se usa solo para manejar valores, básicamente un registro o un mapa de tipo seguro (y de rendimiento). A menudo necesito convertir este objeto en pares de valores clave (ya sean cadenas o tipo seguro) o convertir de pares de valores clave a este objeto.
Aparte de la reflexión o la escritura manual de código para realizar esta conversión, ¿cuál es la mejor manera de lograrlo?
Un ejemplo podría ser enviar este objeto a través de jms, sin usar el tipo ObjectMessage (o convertir un mensaje entrante al tipo correcto de objeto).
java
reflection
collections
javabeans
Shahbaz
fuente
fuente
java.beans.Introspector
.getBeanInfo()
. Está integrado en el JDK.Respuestas:
Siempre hay beanutils de apache commons pero, por supuesto, usa la reflexión debajo del capó
fuente
java.beans
dependencias muy limitadas en la plataforma. Consulte la pregunta relacionada para obtener más detalles.Muchas soluciones potenciales, pero agreguemos solo una más. Use Jackson (lib de procesamiento JSON) para hacer una conversión "sin json", como:
( esta entrada de blog tiene algunos ejemplos más)
Básicamente, puede convertir cualquier tipo compatible: compatible, lo que significa que si convirtió de tipo a JSON, y de ese JSON a tipo de resultado, las entradas coincidirían (si se configuran correctamente, también pueden ignorar las no reconocidas).
Funciona bien para los casos que uno esperaría, incluidos mapas, listas, matrices, primitivas, POJO similares a frijoles.
fuente
BeanUtils
es bueno, pero no puede manejar matrices y enumeracionesLa generación de código sería la única otra forma en la que puedo pensar. Personalmente, obtuve una solución de reflexión generalmente reutilizable (a menos que esa parte del código sea absolutamente crítica para el rendimiento). Usar JMS parece una exageración (dependencia adicional, y eso ni siquiera es para lo que está destinado). Además, probablemente también use la reflexión debajo del capó.
fuente
Este es un método para convertir un objeto Java en un mapa
Así es como se llama
fuente
Probablemente tarde para la fiesta. Puede utilizar Jackson y convertirlo en un objeto Propiedades. Esto es adecuado para clases anidadas y si desea la clave en el valor para abc =.
si quieres un sufijo, hazlo
Necesito agregar esta dependencia
fuente
Con Java 8 puedes probar esto:
fuente
JSON , por ejemplo, usando XStream + Jettison, es un formato de texto simple con pares clave-valor. Es compatible, por ejemplo, con el intermediario de mensajes Apache ActiveMQ JMS para el intercambio de objetos Java con otras plataformas / lenguajes.
fuente
Simplemente usando reflexión y Groovy:
fuente
Utilice BeanWrapper de juffrou- reflect. Es muy eficaz.
Así es como puede transformar un bean en un mapa:
Yo mismo desarrollé Juffrou. Es de código abierto, por lo que puede usarlo y modificarlo libremente. Y si tiene alguna pregunta al respecto, estaré más que feliz de responder.
Salud
Carlos
fuente
Cuando se usa Spring, también se puede usar Spring Integration object-to-map-transformer. Probablemente no valga la pena agregar Spring como una dependencia solo para esto.
Para obtener documentación, busque "Object-to-Map Transformer" en http://docs.spring.io/spring-integration/docs/4.0.4.RELEASE/reference/html/messaging-transformation-chapter.html
Esencialmente, atraviesa todo el gráfico del objeto accesible desde el objeto dado como entrada y produce un mapa de todos los campos de tipo / cadena primitivos en los objetos. Se puede configurar para generar:
Aquí hay un ejemplo de su página:
La salida será:
También está disponible un transformador inverso.
fuente
Podrías usar el marco de Joda:
http://joda.sourceforge.net/
y aprovechar JodaProperties. Sin embargo, esto estipula que debe crear beans de una manera particular e implementar una interfaz específica. Sin embargo, entonces le permite devolver un mapa de propiedad de una clase específica, sin reflexión. El código de muestra está aquí:
http://pbin.oogly.co.uk/listings/viewlistingdetail/0e78eb6c76d071b4e22bbcac748c57
fuente
Si no desea codificar las llamadas a cada getter y setter, la reflexión es la única forma de llamar a estos métodos (pero no es difícil).
¿Puede refactorizar la clase en cuestión para usar un objeto de Propiedades para contener los datos reales y dejar que cada captador y configurador simplemente llame a get / set en él? Entonces tienes una estructura adecuada para lo que quieres hacer. Incluso existen métodos para guardarlos y cargarlos en forma de clave-valor.
fuente
La mejor solución es utilizar Dozer. Solo necesita algo como esto en el archivo del asignador:
Y eso es todo, Dozer se encarga del resto !!!
URL de documentación de Dozer
fuente
Por supuesto, existe el medio de conversión más simple posible: ¡ninguna conversión en absoluto!
en lugar de usar variables privadas definidas en la clase, haga que la clase contenga solo un HashMap que almacena los valores de la instancia.
Luego, sus captadores y definidores regresan y establecen valores dentro y fuera del HashMap, y cuando sea el momento de convertirlo en un mapa, ¡listo! - ya es un mapa.
Con un poco de magia AOP, incluso podría mantener la inflexibilidad inherente a un bean al permitirle seguir usando getters y setters específicos para cada nombre de valor, sin tener que escribir realmente los getters y setters individuales.
fuente
Puede usar las propiedades del colector de filtros de flujo de Java 8,
fuente
Mi procesador de anotaciones JavaDude Bean genera código para hacer esto.
http://javadude.googlecode.com
Por ejemplo:
Lo anterior genera una superclase PersonGen que incluye un método createPropertyMap () que genera un mapa para todas las propiedades definidas usando @Bean.
(Tenga en cuenta que estoy cambiando ligeramente la API para la próxima versión; el atributo de anotación será defineCreatePropertyMap = true)
fuente
¡Debería escribir un servicio de transformación genérico! Use genéricos para mantenerlo libre de tipos (para que pueda convertir cada objeto a key => value y viceversa).
¿Qué campo debería ser la clave? Obtenga ese campo del bean y agregue cualquier otro valor no transitorio en un mapa de valores.
El camino de regreso es bastante sencillo. Lea la clave (x) y escriba primero la clave y luego cada entrada de la lista en un nuevo objeto.
¡Puede obtener los nombres de propiedad de un bean con apache commons beanutils !
fuente
Si realmente desea rendimiento, puede seguir la ruta de generación de código.
Puede hacer esto por su cuenta haciendo su propia reflexión y construyendo una mezcla en AspectJ ITD.
O puede usar Spring Roo y hacer un complemento Spring Roo . Su complemento Roo hará algo similar a lo anterior, pero estará disponible para todos los que usen Spring Roo y no es necesario que use las anotaciones en tiempo de ejecución.
He hecho ambas cosas. La gente caga en Spring Roo, pero realmente es la generación de código más completa para Java.
fuente
Otra forma posible es aquí.
BeanWrapper ofrece funcionalidad para establecer y obtener valores de propiedad (individualmente o en forma masiva), obtener descriptores de propiedad y consultar propiedades para determinar si se pueden leer o escribir.
fuente
Si se trata de un mapeo simple de un árbol de objetos a una lista de valores clave, donde la clave puede ser una descripción de la ruta con puntos desde el elemento raíz del objeto hasta la hoja que se está inspeccionando, es bastante obvio que una conversión de árbol a una lista de valores clave es comparable a una objeto a mapeo xml. Cada elemento dentro de un documento XML tiene una posición definida y se puede convertir en una ruta. Por lo tanto, tomé XStream como una herramienta de conversión básica y estable y reemplacé las partes jerárquicas del controlador y del escritor con una implementación propia. XStream también viene con un mecanismo de seguimiento de ruta básico que, al combinarse con los otros dos, conduce estrictamente a una solución adecuada para la tarea.
fuente
Con la ayuda de la biblioteca de Jackson, pude encontrar todas las propiedades de clase de tipo String / integer / double y los valores respectivos en una clase Map. (¡ sin usar reflections api! )
fuente
Al usar Gson,
object
a JsonConvertir Json en mapa
fuente
Podemos usar la biblioteca Jackson para convertir un objeto Java en un mapa fácilmente.
Si lo usa en un proyecto de Android, puede agregar jackson en build.gradle de su aplicación de la siguiente manera:
Implementación de muestra
Salida:
{nombre = XYZ, id = 1011, habilidades = [python, java]}
fuente