RSS

Schlagwort-Archive: xml

JSON Provider erstellen. Part 7: Konvertierung JSONXML


Im folgenden wird die Umwandlung von JSON in XML mit Java beschrieben. Die JSON-lib bietet mit dem JSONSerializer die Möglichkeit nahezu jedes Java-Objekt in die JSON-Notation zu konvertieren. Mit dem XMLSerializer kann man JSON Objekte in die XML-Notation und zurück umwandeln.

Um die JSON-lib benutzen zu können, sind mindestens folgende Libraries zusätzlich notwendig:

Vorbereitung

Erstellen Sie z.B. in Eclipse ein neues Java Projekt und binden Se die o.g. Libraries (inklusive der JSON-lib) in Ihr Projekt ein.
 

 

JSON>XML

Im folgenden Beispiel wird ein JSON String erstellt und aus diesem der korrespondierende XML String erstellt. Die Klasse „XMLSerializer“ bietet über die write-Methode alle Voraussetzungen, um diese Aufgabe zu erledigen:

package org.jkhofmann.dyndns;

import net.sf.json.JSON;
import net.sf.json.JSONArray;
import net.sf.json.JSONSerializer;
import net.sf.json.xml.XMLSerializer;

public class JSON2XMLConverter {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		String jsonStr = "{'foo':'bar'," +
						 "'coolness':2.0," +
				         "'altitude':39000," +
				         "'pilot':{'firstName':'Buzz'," +
				         "'lastName':'Aldrin'}," +
				         "'mission':'apollo 11'}";

        XMLSerializer serializer = new XMLSerializer();
        JSON json = JSONSerializer.toJSON( jsonStr );
        String xml = serializer.write( json );
        System.out.println(xml);
	}
}

Die (formatierte) Ausgabe:

<?xml version="1.0" encoding="UTF-8"?>
<o>
  <altitude type="number">39000</altitude>
  <coolness type="number">2.0</coolness>
  <foo type="string">bar</foo>
  <mission type="string">apollo 11</mission>
  <pilot class="object">
    <firstName type="string">Buzz</firstName>
    <lastName type="string">Aldrin</lastName>
  </pilot>
</o>

Will man den Typen-Hinweis ausschalten, gibt man folgenden Befehl „serializer.setTypeHintsEnabled(false);“ vor der Serialisierung ein:

...

        JSON json = JSONSerializer.toJSON( jsonStr );
        serializer.setTypeHintsEnabled(false);
        String xml = serializer.write( json );
...

Die entsprechende Ausgabe sieht dann so aus:

<?xml version="1.0" encoding="UTF-8"?>
<o>
  <altitude>39000</altitude>
  <coolness>2.0</coolness>
  <foo>bar</foo>
  <mission>apollo 11</mission>
  <pilot>
    <firstName>Buzz</firstName>
    <lastName>Aldrin</lastName>
  </pilot>
</o>

Soll der Name des Wurzel-Knotens von „<o>“ z.B. nach „<SampleJSON>“ umbenannt werden, dann gibt man den Befehl „serializer.setRootName(„SampleJSON“)“ ein. Die Ausgabe sieht dann so aus:

<?xml version="1.0" encoding="UTF-8"?>
<SampleJSON>
  <altitude>39000</altitude>
  <coolness>2.0</coolness>
  <foo>bar</foo>
  <mission>apollo 11</mission>
  <pilot>
    <firstName>Buzz</firstName>
    <lastName>Aldrin</lastName>
  </pilot>
</SampleJSON>

 

Hinweis: Will man anstelle eines String einen InputStream umwandeln, leistet die Apache Commons IOUtils Library hilfreiche Dienste.

// is comes as a InputStream object and will be
// converted to a String:
String jsonData = IOUtils.toString(is);

 

XML > JSON

Um einen XML String in einen JSON String umzuwandeln, kann man wieder die Klasse „XMLSerializer“ verwenden, diesmal aber über die read-Methode:

JSON jsonout = serializer.read( xml );

Beispiel: Die Klasse wandelt einen JSON String in einen XML String um und anschließend wieder in einen JSON String:

package org.jkhofmann.dyndns;

import net.sf.json.JSON;
import net.sf.json.JSONArray;
import net.sf.json.JSONSerializer;
import net.sf.json.xml.XMLSerializer;

public class JSON2XMLConverter {

	/**
	 * @param args
	 */
	public static void main(String[] args) {

		// JSON Eingabestring:
		String jsonStr = "{'foo':'bar'," +
						 "'coolness':2.0," +
				         "'altitude':39000," +
				         "'pilot':{'firstName':'Buzz'," +
				         "'lastName':'Aldrin'}," +
				         "'mission':'apollo 11'}";

		// Konvertierung nach XML:
        XMLSerializer serializer = new XMLSerializer();
        JSON json = JSONSerializer.toJSON( jsonStr );
        serializer.setTypeHintsEnabled(false);
        serializer.setRootName("SampleJSON");
        String xml = serializer.write( json );
        System.out.println(xml);
        // Konvertierung zurück nach JSON:
        JSON jsonout = serializer.read( xml );
        System.out.println( jsonout );
	}
}

Ausgabe des JSON Strings:

{"altitude":"39000",
 "coolness":"2.0",
 "foo":"bar",
 "mission":"apollo 11",
 "pilot":{
    "firstName":"Buzz",
    "lastName":"Aldrin"
 }
}

 

Links

Wie immer ist ein Großteil der Kenntnisse und Beispiele, de ich hier wiedergebe, nicht auf meinem „eigenen Mist“ gewachsen. Deshalb möchte ich hier die verwendeten Links und weitere Fundstellen nennen:

 
Hinterlasse einen Kommentar

Verfasst von - Februar 23, 2012 in IT, WebServices

 

Schlagwörter: , , ,

JAXB mit Eclipse nutzen

JAXB mit Eclipse nutzen

Java Architecture for XML Binding (JAXB) ermöglicht den einfachen Umgang mit XML Dateien und Java. Man kann damit Java-Klassen erstellen, die auf Schema-Definitionen (z.B. XSD) von XML Dateien beruhen und diese dann einlesen und weiterverarbeiten. Die umgekehrte Richtung, also das Generieren von XML Dateien aus Java-Klassen ist damit ebenfalls möglich. Beides wird in diesem Artikel behandelt.

 

Voraussetzungen:

Java 1.6

Eclipse IDE for Java EE Developers, ich verwende hier das Indigo Release

Download einer aktuellen JAXB Version, z.B. 2.2.41.

Download JAXB-Eclipse-Plugin, z.B. JAXB-Builder

 

Installation/Konfiguration:

Java und die Eclipse IDE kann man einfach herunterladen und installieren. JAXB kann man an einem zentralen Ort speichern, um später die Libraries und evtl. Tools verwenden zu können (z.B. in den Classpath des Eclipse-Projektes einzubinden) – ich verwende hierfür meist das Verzeichnis „C:Program Files (x86)Java“

Das JAXB Eclipse Plugin muss man entpacken und im Plugin-Verzeichnis der Eclipse-Installation kopieren. Danach Eclipse neu starten. Falls der Wizard über „File > New > Project > JAXB“ nicht sichtbar ist, sollte man Eclipse beenden und mit dem Parameter „-clean“ neu starten, um den Plugin-Cache zu leeren.

 

Erst mal ohne Plugin…:

Um einen ersten Einblick in JAXB zu gewinnen, will ich veranschaulichen, wie man Klassen erstellt, ohne das Eclipse-Plugin zu nutzen. Der erste Schritt besteht darin, sich im Klaren zu sein, welche Daten man verarbeiten will und wie man diese in einer XML-Datei darstellen würde.

Im folgenden Beispiel will ich eine Anwendung erstellen, die in der Lage ist XML-Dateien zu verarbeiten, die Kontakte beinhaltet. Der Aufbau dieser XML-Datei könnte wie folgt aussehen:

<Kontakte>
	<Kontakt>
		<Name>Name1</Name>
		<Vorname>Vorname1</Vorname>
		<eMail>eMail1</eMail>
	</Kontakt>
	<Kontakt>
		<Name>Name2</Name>
		<Vorname>Vorname2</Vorname>
		<eMail>eMail2</eMail>
	</Kontakt>
	<Kontakt>
		<Name>Name3</Name>
		<Vorname>Vorname3</Vorname>
		<eMail>eMail3</eMail>
	</Kontakt>
</Kontakte>

Es gibt eine Vielzahl von Online-Tools, die eine Umwandlung der XML-Datei in eine XSD-Datei (XML-Schema) ermöglichen, z.B. http://www.xmlforasp.net. Das Ergebnis sieht dann wie folgt aus:

<?xml version="1.0" encoding="utf-16"?>
<xsd:schema attributeFormDefault="unqualified" elementFormDefault="qualified" version="1.0" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
  <xsd:element name="Kontakte">
    <xsd:complexType>
      <xsd:sequence>
        <xsd:element maxOccurs="unbounded" name="Kontakt">
          <xsd:complexType>
            <xsd:sequence>
              <xsd:element name="Name" type="xsd:string" />
              <xsd:element name="Vorname" type="xsd:string" />
              <xsd:element name="eMail" type="xsd:string" />
            </xsd:sequence>
          </xsd:complexType>
        </xsd:element>
      </xsd:sequence>
    </xsd:complexType>
  </xsd:element>
</xsd:schema>

Jetzt ist es an der Zeit mit Eclipse ein Java Projekt zu erstellen. Die XSD- und die XML-Datei können der Vollständigkeit halber in das Projektverzeichnis kopiert oder dort angelegt werden.

Mit dem Download der JAXB Version werden zwei Skriptdateien mit ausgeliefert, die im „bin“ Unterverzeichnis zu finden sind:

  • „xjc“, um eine XML-Schemadatei in vollständig annotierte Java-Klassen zu kompilieren
  • „schemagen“, um eine XML-Schemadatei aus Java-Klassen zu generieren

Mit dem „xjc“ Tool ist es also möglich, aus der Schema-Datei „Kontakte.xsd“ die entsprechenden JAXB-Java-Klassen zu generieren:

Die generierten Klassen werden im Unterverzeichnis „generated“ gespeichert. Ich kopieren das Verzeichnis in den src Unterordner des Eclipse Projektes und aktualisiere das Projektverzeichnis:

Es werden folgende Klassen und Methoden generiert:

Um die JAXB-Klassen nutzen zu können, müssen die im „lib“-Unterverzeichnis vorhandenen jar Dateien in den Build-Path des Projektes eingebunden werden:

Eine Anwendung, die die XML-Datei parst und weiterverarbeitet könnte etwa so aussehen:

package org.jkhofmann.dyndns;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import generated.*;

public class ParseKontakte {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			// create JAXB context and instantiate marshaller
			JAXBContext context = JAXBContext.newInstance(Kontakte.class);
			Marshaller m = context.createMarshaller();

			// get variables from our xml file, created before
			System.out.println();
			System.out.println("Kontakte XML File: ");
			Unmarshaller um = context.createUnmarshaller();
			Kontakte kontakte = (Kontakte) um.unmarshal(new FileReader(
					"Kontakte.xml"));

			for (int i = 0; i < kontakte.getKontakt().toArray().length; i++) {
				System.out.println("Kontakt " + (i + 1) + ": "
						+ "Name: " + kontakte.getKontakt().get(i).getName() + ", "
						+ "Vorame: " + kontakte.getKontakt().get(i).getVorname() + ", "
						+ "eMail: " + kontakte.getKontakt().get(i).getEMail() + ", "
						);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

Die entsprechende Ausgabe:

Kontakte XML File:
Kontakt 1: Name: Name1, Vorame: Vorname1, eMail: eMail1,
Kontakt 2: Name: Name2, Vorame: Vorname2, eMail: eMail2,
Kontakt 3: Name: Name3, Vorame: Vorname3, eMail: eMail3,

In einem weiteren Schritt will ich den Inhalt bearbeiten und erweitern:

package org.jkhofmann.dyndns;

import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.Writer;
import java.util.ArrayList;

import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Marshaller;
import javax.xml.bind.Unmarshaller;

import generated.*;

public class ParseKontakte {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		try {
			// create JAXB context and instantiate marshaller
			JAXBContext context = JAXBContext.newInstance(Kontakte.class);
			Marshaller m = context.createMarshaller();

			// get variables from our xml file, created before
			System.out.println();
			System.out.println("Kontakte XML File: ");
			Unmarshaller um = context.createUnmarshaller();
			Kontakte kontakte = (Kontakte) um.unmarshal(new FileReader(
					"Kontakte.xml"));

			for (int i = 0; i < kontakte.getKontakt().toArray().length; i++) {
				System.out.println("Kontakt " + (i + 1) + ": "
						+ "Name: " + kontakte.getKontakt().get(i).getName() + ", "
						+ "Vorame: " + kontakte.getKontakt().get(i).getVorname() + ", "
						+ "eMail: " + kontakte.getKontakt().get(i).getEMail() + ", "
						);
			}

			// Add a new contact:
			Kontakte.Kontakt k = new Kontakte.Kontakt();
			k.setName("Name4");
			k.setVorname("Vorname4");
			k.setEMail("eMail4");

			kontakte.getKontakt().add(k);

			// write the enhanced contact list in a new XML file:
			m.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT, Boolean.TRUE);
			m.marshal(kontakte, System.out);

			Writer w = null;
			try {
				w = new FileWriter("Kontakte2.xml");
				m.marshal(kontakte, w);
			} finally {
				try {
					w.close();
				} catch (Exception e) {
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
}

Die Ausgabe („Kontakte2.xml“):

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Kontakte>
    <Kontakt>
        <Name>Name1</Name>
        <Vorname>Vorname1</Vorname>
        <eMail>eMail1</eMail>
    </Kontakt>
    <Kontakt>
        <Name>Name2</Name>
        <Vorname>Vorname2</Vorname>
        <eMail>eMail2</eMail>
    </Kontakt>
    <Kontakt>
        <Name>Name3</Name>
        <Vorname>Vorname3</Vorname>
        <eMail>eMail3</eMail>
    </Kontakt>
    <Kontakt>
        <Name>Name4</Name>
        <Vorname>Vorname4</Vorname>
        <eMail>EMail4</eMail>
    </Kontakt>
</Kontakte>

Ich finde, die Anwendung von JAXB ist im Vergleich zur Anwendung von SAX- oder DOM-Parsern (z.B. Xerces oder allgemeiner  Java API for XML Processing – JAXP), wesentlich einfacher und zeitsparender. Anwender der Eclipse IDE können sich zusätzlich das Plugin „JAXB-Builder“ installieren. Die Anwendung wird im folgenden erläutert.

Jetzt mit dem Plugin…

Dazu erstellt man sich ein neues Projekt über „File > New > Project > JAXB“ und kopiert die XSD-Datei hinein:

Damit das Plugin funktioniert, muss man (wie gehabt) den Build-Path des Projektes um die JAXB-Libraries erweitern:

Durch einen Rechtsklick auf die XSD-Datei > Generate > JAXB Classes… kann man sich die JAXB-Klassen generieren lassen. Das Ergebnis ist das Gleiche wie oben, d.h. das Ausprogrammieren ist noch notwendig.

Man erspart sich allerdings den Umweg über die Kommandozeile, zum Generieren der JAXB-Java-Klassen.

 
Ein Kommentar

Verfasst von - Februar 3, 2012 in Formate, IT

 

Schlagwörter: , , , ,

JSON Provider erstellen. Part 3: Axis2 spricht JSON


In diesem letzten Teil geht es darum, Axis2 Services, Antworten in JSON schicken zu lassen.

In Teil 1 ging es darum „Apache Tomcat zu installieren„, in Teil 2 ging es darum „Axis2 auf Tomcat zu installieren„. In diesem dritten Teil geht es nur noch darum die Antworten von Axis2 Services nicht mehr in XML, sondern auch in JSON zu liefern.

Alles was ich im Folgenden beschreibe geht letztendlich auf den Artikel „Building a JSON web service with Java and Axis2“ von Markus Schiesser zurück. Im Wesentlichen geht es um einen Bug in Axis2, bei der Nutzung der Jettison API, um JSON Nachrichten zu parsen. In einem weiteren Artikel „JSON web service with Java and Axis2„, von DJaka PM, wird die Beschreibung von Markus Schiesser nochmals vereinfacht und soll im Folgenden veranschaulicht werden.

  1. Laden Sie sich die modifizierte WAR Datei hier oder hier herunter.
  2. Sichern Sie Ihre Inhalte in Axis2, diese werden überschrieben !
  3. Installieren Sie die neue WAR Datei in Axis2:
    sudo cp <Download Verzeichnis>/axis2.war ./webapps/

    Warten Sie einen Augenblick

  4. Stellen Sie sicher, daß Tomcat gestartet ist und rufen Sie folgenden Link auf:
    http://localhost:8080/axis2/services/Version/getVersion?response=application/json

    Es müsste folgende Antwort in Ihrem Web-Browser erscheinen:

  5. Wollen Sie die herkömmliche XML-formatierte Antwort, dann rufen Sie einfach folgenden Link auf:
    http://localhost:8080/axis2/services/Version/getVersion

    Es müsste folgende Antwort in Ihrem Web-Browser erscheinen:

Je nach URL, erhalten Sie also eine JSON- oder XML-formatierte Antwort des WebServices.

 
Hinterlasse einen Kommentar

Verfasst von - Dezember 31, 2011 in WebServices

 

Schlagwörter: , , ,

OData: Antwort in AtomPub, JSON oder XML


Die Rückgabe kann in AtomPub (Atom Publishing Protocol), JSON (JavaScript Object Notation) oder XML (Extensible Markup Langugage) erfolgen.

Atom ist der standardisierte Nachfolger des RSS Formats und nutzt XML als Basis. Es wird genutzt um sog. „Feeds“ zu abonnieren,also elektronische Nachrichten, die mehr oder weniger regelmäßig publiziert werden. Neben den allgemeinen Daten, wie Titel, Link, Autor, enthält die Nachricht ein Element „entry“, in welchem der eigentliche Inhalt abgelegt wird.

Beispiel:

<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Example Feed</title>
  <link href="http://example.org/"/>
  <updated>2003-12-13T18:30:02Z</updated>
  <author>
    <name>John Doe</name>
  </author>
  <id>urn:uuid:60a76c80-d399-11d9-b93C-0003939e0af6</id>
  <entry>
    <title>Atom-Powered Robots Run Amok</title>
    <link href="http://example.org/2003/12/13/atom03"/>
    <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
    <updated>2003-12-13T18:30:02Z</updated>
    <summary>Some text.</summary>
  </entry>
</feed>

Innerhalb des „entry“ Tags kann es noch das „content“ Tag geben, das jeden beliebigen MIME Typ als Inhalt erlaubt.

Beispiel:

<entry>
    <title>Atom-Powered Robots Run Amok</title>
    <id>urn:uuid:1225c695-cfb8-4ebb-aaaa-80da344efa6a</id>
    <updated>2003-12-13T18:30:02Z</updated>
    <content type="xhtml">
     <div xmlns="http://www.w3.org/1999/xhtml">
        Those robots were <i>crazy</i>! ...
     </div>
    </content>
  </entry>

Während Atom lediglich das Lesen von elektronischen Nachrichten erlaubt, kann AtomPub auch neue Daten bzw. Nachrichten erzeugen, bestehende verändern oder löschen. Die Manipulation der Nachrichten erfolgt über die HTTP Operationen GET, POST, PUT und DELETE.

Die OData Spezifikation erweitert AtomPub um ein Datenmodell, d.h. Datentypen und um die Festlegung, wo die Daten zu finden sind. Diese Festlegung erfolgt in der URL.

Die Antwort kann neben Atom/AtomPub oder XML auch in JSON erfolgen, indem im Request als Accept type to “application/json” angegeben wird.

Beispiel:

{
  "Herausgeber": "Xema",
  "Nummer": "1234-5678-9012-3456",
  "Deckung": 2e+6,
  "Währung": "EURO",
  "Inhaber": {
    "Name": "Mustermann",
    "Vorname": "Max",
    "männlich": true,
    "Hobbys": [ "Reiten", "Golfen", "Lesen" ],
    "Alter": 42,
    "Kinder": [],
    "Partner": null
  }
}

JSON wird oft im Zusammenhang mit AJAX verwendet. Der folgende JavaScript Code zeigt, wie auf einem Client mit  XMLHttpRequest ein Response in JSON Format angefordert werden kann:

var my_JSON_object = {};
var http_request = new XMLHttpRequest();
http_request.open("GET", url, true);
http_request.onreadystatechange = function () {
  var done = 4, ok = 200;
  if (http_request.readyState == done && http_request.status == ok) {
       my_JSON_object = JSON.parse(http_request.responseText);
  }
};
http_request.send(null);

JSON entspricht dem JavaScript Format und ist intuitiv einfacher zu lesen als XML. Durch die Tag-Struktur in XML werden Elemente teilweise erheblich aufgebläht. In JSON können die Daten beliebig verschachtelt werden, beispielsweise ist ein Array von Objekten möglich. Zudem gibt es Datentypen. Als Zeichenkodierung benutzt JSON standardmäßig UTF-8; UTF-16 und UTF-32 sind auch möglich. Der MIME-Typ für JSON Dokumente ist „application/json„.

 

Links:

MSDN

RFC 4287

JSON (Wikipedia, OData.org)

OData Org

REW

 
Hinterlasse einen Kommentar

Verfasst von - Dezember 21, 2011 in Formate

 

Schlagwörter: , , ,

 
Erstelle eine Website wie diese mit WordPress.com
Jetzt starten