Angenommen, ich habe ein sehr einfaches Java-Objekt, das nur einige getXXX- und setXXX-Eigenschaften hat. Dieses Objekt wird nur verwendet, um Werte zu verarbeiten, im Grunde genommen einen Datensatz oder eine typsichere (und performante) Zuordnung. Ich muss dieses Objekt oft in Schlüsselwertpaare (entweder Zeichenfolgen oder Typ Safe) umwandeln oder von Schlüsselwertpaaren in dieses Objekt konvertieren.
Was ist der beste Weg, um dies zu erreichen, außer Reflexion oder manuelles Schreiben von Code für diese Konvertierung?
Ein Beispiel könnte das Senden dieses Objekts über jms sein, ohne den ObjectMessage-Typ zu verwenden (oder eine eingehende Nachricht in den richtigen Objekttyp zu konvertieren).
java
reflection
collections
javabeans
Shahbaz
quelle
quelle
java.beans.Introspector
.getBeanInfo()
. Es ist direkt in das JDK integriert.Antworten:
Es gibt immer Apache Commons Beanutils, aber natürlich wird unter der Haube reflektiert
quelle
java.beans
Abhängigkeiten verwendet werden, die auf der Plattform stark eingeschränkt sind. Einzelheiten finden Sie in der entsprechenden Frage .Viele mögliche Lösungen, aber fügen wir noch eine hinzu. Verwenden Sie Jackson (JSON-Verarbeitungsbibliothek), um eine "json-less" -Konvertierung durchzuführen, z.
( dieser Blogeintrag enthält weitere Beispiele.)
Grundsätzlich können Sie alle kompatiblen Typen konvertieren: Kompatibel bedeutet, dass bei einer Konvertierung von Typ zu JSON und von diesem JSON zu Ergebnistyp die Einträge übereinstimmen würden (bei ordnungsgemäßer Konfiguration können auch nicht erkannte Typen einfach ignoriert werden).
Funktioniert gut für Fälle, die man erwarten würde, einschließlich Karten, Listen, Arrays, Grundelemente und bohnenähnliche POJOs.
quelle
BeanUtils
ist nett, kann aber nicht mit Arrays und Enums umgehenDie Codegenerierung wäre der einzige andere Weg, den ich mir vorstellen kann. Persönlich hatte ich eine allgemein wiederverwendbare Reflexionslösung (es sei denn, dieser Teil des Codes ist absolut leistungskritisch). Die Verwendung von JMS klingt nach Overkill (zusätzliche Abhängigkeit, und dafür ist sie nicht einmal gedacht). Außerdem wird wahrscheinlich auch Reflexion unter der Haube verwendet.
quelle
Dies ist eine Methode zum Konvertieren eines Java-Objekts in eine Map
So nennt man es
quelle
Wahrscheinlich zu spät zur Party. Sie können Jackson verwenden und in ein Eigenschaftenobjekt konvertieren. Dies ist für verschachtelte Klassen geeignet und wenn Sie den Schlüssel für for abc = value möchten.
Wenn Sie ein Suffix möchten, tun Sie es einfach
müssen diese Abhängigkeit hinzufügen
quelle
Mit Java 8 können Sie Folgendes versuchen:
quelle
JSON , beispielsweise mit XStream + Jettison, ist ein einfaches Textformat mit Schlüsselwertpaaren. Es wird beispielsweise vom Apache ActiveMQ JMS-Nachrichtenbroker für den Java-Objektaustausch mit anderen Plattformen / Sprachen unterstützt.
quelle
Einfach mit Reflection und Groovy:
quelle
Verwenden Sie Juffrou-Reflect Reflect. Es ist sehr performant.
So können Sie eine Bohne in eine Karte verwandeln:
Ich habe Juffrou selbst entwickelt. Es ist Open Source, Sie können es also verwenden und ändern. Und wenn Sie Fragen dazu haben, werde ich Ihnen gerne antworten.
Prost
Carlos
quelle
Bei Verwendung von Spring kann auch der Objektintegrationstransformator von Spring Integration verwendet werden. Es lohnt sich wahrscheinlich nicht, Spring nur dafür als Abhängigkeit hinzuzufügen.
Suchen Sie zur Dokumentation nach "Object-to-Map Transformer" auf http://docs.spring.io/spring-integration/docs/4.0.4.RELEASE/reference/html/messaging-transformation-chapter.html
Im Wesentlichen durchläuft es den gesamten Objektgraphen, der von dem als Eingabe angegebenen Objekt aus erreichbar ist, und erstellt eine Karte aus allen primitiven Typ- / Zeichenfolgenfeldern auf den Objekten. Es kann so konfiguriert werden, dass Folgendes ausgegeben wird:
Hier ist ein Beispiel von ihrer Seite:
Ausgabe wird sein:
Ein Rücktransformator ist ebenfalls erhältlich.
quelle
Sie können das Joda-Framework verwenden:
http://joda.sourceforge.net/
und nutzen Sie JodaProperties. Dies setzt jedoch voraus, dass Sie Beans auf eine bestimmte Weise erstellen und eine bestimmte Schnittstelle implementieren. Sie können dann jedoch eine Eigenschaftskarte einer bestimmten Klasse ohne Reflexion zurückgeben. Beispielcode ist hier:
http://pbin.oogly.co.uk/listings/viewlistingdetail/0e78eb6c76d071b4e22bbcac748c57
quelle
Wenn Sie nicht Aufrufe an jeden Getter und Setter fest codieren möchten, ist Reflektion die einzige Möglichkeit, diese Methoden aufzurufen (dies ist jedoch nicht schwierig).
Können Sie die betreffende Klasse so umgestalten, dass sie ein Eigenschaftenobjekt verwendet, um die tatsächlichen Daten zu speichern, und jeden Getter und Setter einfach get / set aufrufen lassen? Dann haben Sie eine Struktur, die gut zu dem passt, was Sie tun möchten. Es gibt sogar Methoden, um sie im Schlüsselwertformular zu speichern und zu laden.
quelle
Die beste Lösung ist die Verwendung von Dozer. Sie brauchen nur so etwas in der Mapper-Datei:
Und das war's, Dozer kümmert sich um den Rest !!!
Dozer-Dokumentations-URL
quelle
Es gibt natürlich das absolut einfachste Konvertierungsmittel - überhaupt keine Konvertierung!
Anstatt private Variablen zu verwenden, die in der Klasse definiert sind, muss die Klasse nur eine HashMap enthalten, in der die Werte für die Instanz gespeichert sind.
Dann kehren Ihre Getter und Setter zurück und setzen Werte in und aus der HashMap, und wenn es Zeit ist, sie in eine Karte umzuwandeln, voila! - Es ist bereits eine Karte.
Mit ein wenig AOP-Zauberei können Sie sogar die Inflexibilität einer Bean beibehalten, indem Sie weiterhin Getter und Setter verwenden, die für jeden Wertnamen spezifisch sind, ohne die einzelnen Getter und Setter tatsächlich schreiben zu müssen.
quelle
Sie können die Java 8 Stream Filter Collector-Eigenschaften verwenden.
quelle
Mein JavaDude Bean Annotation Processor generiert dazu Code.
http://javadude.googlecode.com
Beispielsweise:
Das Obige generiert PersonGen der Oberklasse, das eine createPropertyMap () -Methode enthält, die eine Map für alle mit @Bean definierten Eigenschaften generiert.
(Beachten Sie, dass ich die API für die nächste Version geringfügig ändere. Das Annotation-Attribut lautet defineCreatePropertyMap = true.)
quelle
Sie sollten einen generischen Transformationsdienst schreiben! Verwenden Sie Generika, um den Typ frei zu halten (damit Sie jedes Objekt in key => value und back konvertieren können).
Welches Feld sollte der Schlüssel sein? Holen Sie sich dieses Feld aus der Bean und fügen Sie einen anderen nicht vorübergehenden Wert in eine Wertezuordnung ein.
Der Rückweg ist ziemlich einfach. Lesen Sie den Schlüssel (x) und schreiben Sie zuerst den Schlüssel und dann jeden Listeneintrag zurück in ein neues Objekt.
Sie können die Eigenschaftsnamen einer Bean mit den Apache Commons Beanutils erhalten !
quelle
Wenn Sie wirklich wirklich Leistung wollen, können Sie den Weg der Codegenerierung gehen.
Sie können dies auf eigene Faust tun, indem Sie Ihre eigenen Überlegungen anstellen und eine Mischung aus AspectJ ITD erstellen.
Oder Sie können Spring Roo verwenden und ein Spring Roo Addon erstellen . Ihr Roo-Addon wird etwas Ähnliches wie oben tun, steht jedoch jedem zur Verfügung, der Spring Roo verwendet, und Sie müssen keine Laufzeitanmerkungen verwenden.
Ich habe beides getan. Die Leute scheißen auf Spring Roo, aber es ist wirklich die umfassendste Codegenerierung für Java.
quelle
Ein anderer möglicher Weg ist hier.
Der BeanWrapper bietet Funktionen zum Festlegen und Abrufen von Eigenschaftswerten (einzeln oder in großen Mengen), zum Abrufen von Eigenschaftsbeschreibungen und zum Abfragen von Eigenschaften, um festzustellen, ob sie lesbar oder beschreibbar sind.
quelle
Wenn es sich um eine einfache Zuordnung von Objektbaum zu Schlüsselwertliste handelt, bei der der Schlüssel eine gepunktete Pfadbeschreibung vom Stammelement des Objekts zum zu prüfenden Blatt sein kann, ist es ziemlich offensichtlich, dass eine Baumkonvertierung in eine Schlüsselwertliste mit einer vergleichbar ist Objekt zu XML-Zuordnung. Jedes Element in einem XML-Dokument hat eine definierte Position und kann in einen Pfad konvertiert werden. Daher habe ich XStream als grundlegendes und stabiles Konvertierungswerkzeug verwendet und die hierarchischen Treiber- und Writer-Teile durch eine eigene Implementierung ersetzt. XStream verfügt außerdem über einen grundlegenden Pfadverfolgungsmechanismus, der in Kombination mit den beiden anderen streng dazu führt, dass eine Lösung für die Aufgabe geeignet ist.
quelle
Mit Hilfe der Jackson-Bibliothek konnte ich alle Klasseneigenschaften vom Typ String / integer / double und die entsprechenden Werte in einer Map-Klasse finden. ( ohne Reflexionen API zu verwenden! )
quelle
Durch die Verwendung von Gson,
object
in JsonKonvertiere Json in Map
quelle
Wir können die Jackson-Bibliothek verwenden, um ein Java-Objekt einfach in eine Map zu konvertieren.
Bei Verwendung in einem Android-Projekt können Sie Jackson wie folgt in build.gradle Ihrer App einfügen:
Beispielimplementierung
Ausgabe:
{name = XYZ, id = 1011, Skills = [Python, Java]}
quelle