RSS

Archiv der Kategorie: WebServices

Chromium + Pocket = „Read It Later“

Chromium + Pocket = „Read It Later“

Mal wieder ein Artikel der nichts direkt mit Lubuntu oder LXDE zu tun hat, sondern auf allen Plattformen funktioniert, die den „Chrome“ bzw. „Chromium“ Browser zur Verfügung stellen.

Motivation

Es passiert mir relativ oft, dass ich einen interessanten Artikel im Internet finde, aber keine Zeit habe, ihn mir vollständig durchzulesen. Im letzten Jahr habe ich dafür „Read It Later“ benutzt, das mittlerweile in „Pocket“ umbenannt wurde. Die Idee dahinter:  Surfen – Artikel in „Pocket“ speichern und wenn man mal Zeit und Lust hat, den Artikel lesen. Das geht ganz einfach, nachdem man sich einen (derzeit kostenlosen) Account zugelegt hat.

 

Vorgehensweise

Es gibt viele Möglichkeiten in den Genuß dieser „Gedächtnisstütze“ zu gelangen, ich will aber hier nur von der Nutzung mit  „Chrome“ bzw. „Chromium“ sprechen. Voraussetzung ist zuallererst ein Account, den man sich über http://getpocket.com/ > „Sign Up now“ zulegen kann. Nachdem man sich registriert hat geht der Spaß los.

Man aktiviert die Applikation „Pocket“ unter https://chrome.google.com/webstore/detail/niloccemoadcdkdjlinkgdfekeahmflj oder sucht sich eine Alternative unter https://chrome.google.com/webstore. Danach erscheint das entsprechende Icon rechts:

Surft man nun eine bestimmte Seite an, die man sich merken will, drückt man dieses Icon (und nach einer einmaligen Anmeldung) werden die Daten im Pocket-Depot abgelegt.

Um auf die gespeicherten Seiten zuzugreifen, sollte man sich in der Symbolleiste noch folgenden Link speichern: http://getpocket.com/a/queue/. Dazu einfach die Seite aufrufen und in die Symbolleiste ziehen:

Will man sich alle gespeicherten Seiten ansehen, klickt man dieses Icon an und sieht die Liste:

Durch einen Klick auf die Schlagzeile kann man sich den Artikel nachträglich anschauen. Man kann den Artikel löschen, archivieren oder favorisieren.

Für Freunde des kleinen „Zwitscherers“ (aka Twitter) besteht sogar die Möglichkeit, Tweets im Pocket-Speicher abzulegen:

 

Fazit

Ich fand schon „Read It Later“ überzeugend, aber mit „Pocket“ scheint alles noch ein bisschen besser durchdacht. Gleichzeitig kann ich die App unter iOS und Android nutzen und das Ganze ist kostenlos 🙂

 
Hinterlasse einen Kommentar

Verfasst von - April 25, 2012 in WebServices

 

Schlagwörter: , , , , , , ,

Chromium + Pocket = "Read It Later"

Chromium + Pocket = "Read It Later"

Mal wieder ein Artikel der nichts direkt mit Lubuntu oder LXDE zu tun hat, sondern auf allen Plattformen funktioniert, die den „Chrome“ bzw. „Chromium“ Browser zur Verfügung stellen.

Motivation

Es passiert mir relativ oft, dass ich einen interessanten Artikel im Internet finde, aber keine Zeit habe, ihn mir vollständig durchzulesen. Im letzten Jahr habe ich dafür „Read It Later“ benutzt, das mittlerweile in „Pocket“ umbenannt wurde. Die Idee dahinter:  Surfen – Artikel in „Pocket“ speichern und wenn man mal Zeit und Lust hat, den Artikel lesen. Das geht ganz einfach, nachdem man sich einen (derzeit kostenlosen) Account zugelegt hat.

 

Vorgehensweise

Es gibt viele Möglichkeiten in den Genuß dieser „Gedächtnisstütze“ zu gelangen, ich will aber hier nur von der Nutzung mit  „Chrome“ bzw. „Chromium“ sprechen. Voraussetzung ist zuallererst ein Account, den man sich über http://getpocket.com/ > „Sign Up now“ zulegen kann. Nachdem man sich registriert hat geht der Spaß los.

Man aktiviert die Applikation „Pocket“ unter https://chrome.google.com/webstore/detail/niloccemoadcdkdjlinkgdfekeahmflj oder sucht sich eine Alternative unter https://chrome.google.com/webstore. Danach erscheint das entsprechende Icon rechts:

Surft man nun eine bestimmte Seite an, die man sich merken will, drückt man dieses Icon (und nach einer einmaligen Anmeldung) werden die Daten im Pocket-Depot abgelegt.

Um auf die gespeicherten Seiten zuzugreifen, sollte man sich in der Symbolleiste noch folgenden Link speichern: http://getpocket.com/a/queue/. Dazu einfach die Seite aufrufen und in die Symbolleiste ziehen:

Will man sich alle gespeicherten Seiten ansehen, klickt man dieses Icon an und sieht die Liste:

Durch einen Klick auf die Schlagzeile kann man sich den Artikel nachträglich anschauen. Man kann den Artikel löschen, archivieren oder favorisieren.

Für Freunde des kleinen „Zwitscherers“ (aka Twitter) besteht sogar die Möglichkeit, Tweets im Pocket-Speicher abzulegen:

 

Fazit

Ich fand schon „Read It Later“ überzeugend, aber mit „Pocket“ scheint alles noch ein bisschen besser durchdacht. Gleichzeitig kann ich die App unter iOS und Android nutzen und das Ganze ist kostenlos 🙂

 
Hinterlasse einen Kommentar

Verfasst von - April 25, 2012 in WebServices

 

Schlagwörter: , , , , , , ,

JAX-WS: Webservices mit SOAP

JAX-WS: Webservices mit SOAP

Nachdem ich bereits JAX-RS in der Reihe „JSON Provider erstellen“ behandelt habe, bleibt noch das Pendant, nämlich JAX-WS über. Während sich JAX-RS mit REST-Services befasst, geht es bei JAX-WS um SOAP. Die Referenzimplementierung für JAX-WS ist unter http://jax-ws.java.net/ zu finden.

Wer sich für JAX-RS interessiert, der sei auf folgende Artikel in diesem Blog verwiesen:

Bei JAX-WS gibt es zwei  Herangehensweisen, wie man einen Web-Service erstellt:

  • Bottom-Up:
    Erstellen der Java-Klassen (POJOs) und generieren des Web-Services
  • Top-Down:
    Erstellen der WSDL und generieren der Java-Klassen daraus

Bottom-Up

Vorgehensweise:

  1. Erstellen eines einfachen „Java“ Projektes in Eclipse.
    Hinweis: Will man den WebService anschließend auf einem Applikationsserver oder Tomcat deployen, macht es mehr Sinn ein Dynamisches Web-Projekt mit EAR als Projekt-Template zu verwenden.
  2. Definition des Web Service Endpoints:
    Ein Web Service Endpoint wird mit @WebService (bzw. javax.jws.WebService) annotiert. Die Klasse ist die Implementierungsklasse des WebServices.
  3. Optional: Definition des Service Endpoint Interfaces (SEI):
    Das SEI ist ein Java-Interface, das die Methoden deklariert, die ein WS Client aufrufen kann. Es ist nicht notwendig SEIs zu deklarieren, da durch die @WebService Annotation der Implementierungsklasse implizit ein SEI deklariert wird. Meiner Meinung nach kann die Verwendung von SEIs aber die Übersichtlichkeit erhöhen. Verwendet man SEIs, dann  muss man in der @WebService Annotation der Implementierungsklasse das Element endpointInterface hinzufügen.
  4. Server zum Starten des WS implementieren bzw. WS deployen
  5. JAX-WS Client implementieren

Ohne SEI

Ohne die Verwendung von SEIs, sieht eine einfache Implementierung eines JAX-WS WebServices wie folgt aus:
package ohnesei;

import javax.jws.WebMethod;
import javax.jws.WebService;

@WebService()
public class Hello {
  private String message = new String("Hello, ");

  public void Hello() {}

  @WebMethod()
  public String sayHello(String name) {
    return message + name + ".";
  }
}
Mit einfachen Mitteln kann man einen Server implementieren, der den WS startet:
package ohnesei;

import javax.xml.ws.Endpoint;

public class TestWsServer
{
   public static void main( final String[] args )
   {
      String url = ( args.length > 0 ) ? args[0] : "http://localhost:4434/miniwebservice";
      Endpoint.publish( url, new Hello() );
   }
}

Inhalt in Eclipse:

Startet man den TestWSServer ohne Argumente, dann kann man sich im Browser die WSDL http://localhost:4434/miniwebservice?wsdl

 

Mit SOAPUI kann man den WebService testen:

 

Mit SEI

Mit Verwendung von SEIs definiert man zusätzlich eine Interface Klasse (das SEI):
package mitsei;

import javax.jws.*;

@WebService
public interface HelloIF
{
   public String sayHello(String name);
}
Die Implementierungklasse sieht dann wie folgt aus:
package mitsei;

import javax.jws.WebService;

@WebService( endpointInterface="mitsei.HelloIF" )
public class Hello implements HelloIF
{
   private String message = new String("Hello, ");

   public void Hello() {}

   public String sayHello(String name) {
       return message + name + "!";
     }
}

Man beachte die Erweiterung:
@WebService( endpointInterface="mitsei.HelloIF" )

Der Server, zum Starten des WS:

package mitsei;

import javax.xml.ws.Endpoint;

import mitsei.Hello;

public class TestWsServer
{
   public static void main( final String[] args )
   {
      String url = ( args.length > 0 ) ? args[0] : "http://localhost:4435/miniwebservice";
      Endpoint.publish( url, new Hello() );
   }
}

Der Client zum Testen:

package mitsei;

import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;

public class TestWsClient
{
   public static void main( final String[] args ) throws Throwable
   {
      String url = ( args.length > 0 ) ? args[0] : "http://localhost:4435/miniwebservice";
      Service service = Service.create(
            new URL( url + "?wsdl" ),
            new QName( "http://mitsei/", "HelloService" ) );
      HelloIF halloWelt = service.getPort( HelloIF.class );
      System.out.println( "n" + halloWelt.sayHello( args.length > 1 ? args[1] : "" ) );
   }
}

Inhalt in Eclipse:

Annotationen

Sowohl das SEI, als auch die Implementierungsklasse müssen mit @WebService annotiert sein (siehe Beispiele vorher). Bei Bedarf kann der Entwickler mittels der Annotationen @WebMethod, @WebParam und@WebResult auf die Schnittstellenbeschreibung Einfluss nehmen.
@WebMethod(operationName="sayHello")
 public @WebResult(name="hellomessage") String sayHello(@WebParam(name="name") String name) {
	    return message + name + "!";
	  }

Mit @Oneway werden Methoden definiert, die asynchronen ausgeführt werden sollen, d.h. der Client wird für die Ausführung der Methode nicht blockiert. Diese Vorgehensweise nach dem Fire-and-Forget-Prinzip funktioniert allerdings nur bei Methoden, die kein Ergebnis zurückliefern.

In der Implementierungsklasse kann man mit @PostConstruct und @PreDestroy Methoden definieren, um Initialisierungs- bzw. Aufräumarbeiten  nach Initialisieren des WebServices bzw. vor dem Zerstören des WebServices zu erledigen.

Top-Down

Der Top-Down Ansatz, auch Contract-First genannt, beruht darauf, aus einer bestehenden Schnittstellen-Beschreibung (WSDL) einen WebService zu erstellen. JAX-WS bietet hierzu das Tool „wsimport“ an, welches aus der vorhandenen WSDL die entsprechenden Java-Artefakte generiert.

Vorausgesetzt, der im letzten Abschnitt erstellte WebService läuft noch, kann man wie folgt die Artefakte erstellen:

juergen@vostro:~$ cd
juergen@vostro:~$ mkdir loeschen
juergen@vostro:~$ cd loeschen
juergen@vostro:~/loeschen$ mkdir generated
juergen@vostro:~/loeschen$ wsimport -d generated http://localhost:4435/miniwebservice?wsdl

Im Beispiel werden die Java-Artefakte in folgendem Verzeichnis abgelegt:

juergen@vostro:~$ ls -R ~/loeschen/generated
/home/juergen/loeschen/generated:
mitsei

/home/juergen/loeschen/generated/mitsei:
HelloIF.class       ObjectFactory.class  SayHello.class
HelloService.class  package-info.class   SayHelloResponse.class

Will man die generierten Java Dateien beibehalten, muss man die Option „-keep“ anwenden:

juergen@vostro:~/loeschen$ wsimport -d generated -keep http://localhost:4435/miniwebservice?wsdl

juergen@vostro:~/loeschen$ ls -R ~/loeschen/generated
/home/juergen/loeschen/generated:
mitsei

/home/juergen/loeschen/generated/mitsei:
HelloIF.class       ObjectFactory.class  SayHello.class
HelloIF.java        ObjectFactory.java   SayHello.java
HelloService.class  package-info.class   SayHelloResponse.class
HelloService.java   package-info.java    SayHelloResponse.java

Mit der Option „-p <Package Name>“ kann man noch einen zu generierenden Package-Namen mitgeben:

juergen@vostro:~/loeschen$ wsimport -d generated -p mitsei.generated -keep http://localhost:4435/miniwebservice?wsdl

juergen@vostro:~/loeschen$ ls -R ~/loeschen/generated
/home/juergen/loeschen/generated:
mitsei

/home/juergen/loeschen/generated/mitsei:
generated

/home/juergen/loeschen/generated/mitsei/generated:
HelloIF.class       ObjectFactory.class  SayHello.class
HelloIF.java        ObjectFactory.java   SayHello.java
HelloService.class  package-info.class   SayHelloResponse.class
HelloService.java   package-info.java    SayHelloResponse.java

Wie kann man sich nun damit einen WebService bauen?

Zuerst kann man die generierten Dateien in das Workspace Verzeichnis von Eclipse kopieren. Da wir bereits ein Projekt mit einem Package „mitsei“ im vorigen Abschnitt erstellt haben, kopieren wir die Dateien einfach hier hinein.

Beispiel:

juergen@vostro:~/workspace/JAXWSTest/src/mitsei$ cp -R ~/loeschen/generated/mitsei/generated .

Anschließend refreshen wir in Eclipse das Projekt (Projekt-Explorer + F5):

In vielen Fällen wird es so sein, dass man eine WSDL von einem bereits existierenden WebService erhält und diesen nun nutzen will. D.h. man erstellt einen Client, der den WebService aufruft. Im folgenden will ich den WebService einfach nutzen. Nachdem ich mir via „wsimport“ alle notwendigen Artefakte erzeugt habe, erstelle ich einen Java-Client, der in der Lage ist, den WebService aufzurufen:

package mitsei.generated;

import javax.xml.ws.BindingProvider;

public class TestWsClient {
	public static void main(String[] args) {

		HelloService service = new HelloService();
		HelloIF port = service.getHelloPort();

		// BindingProvider bp = (BindingProvider) port;
		// bp.getRequestContext().put(BindingProvider.USERNAME_PROPERTY, "test");
		// bp.getRequestContext().put(BindingProvider.PASSWORD_PROPERTY, "test");

		String request = "Jürgen";
		System.out.println (" Request:  "" + request + """ );
		String response = port.sayHello(request);
		System.out.println ("Response:  "" + response + """ );
	}

}

Den Client „TestWsClient“ erstelle ich der Einfachheit halber direkt im Package „mitsei.generated“:

Hier die Ausgabe:

 

XSD und WSDL

Eine XSD (XML Schema Definition) beschreibt den Aufbau einer XML Datei. Sie ist der Nachfolger der klassischen DTD (Document Type Definition).

Die WSDL (Web Services Description Language) hingegen beschreibt den Aufbau eines SOAP WebServices, also u.a. die Operationen bzw. Schnittstellen, deren Übergabe- und Rückgabe-Parameter. Damit ist es auch notwendig, erlaubte bzw. verwendete Datentypen zu beschreiben. Man tut dies in Form einer oder mehrerer XSDs, die man von extern inkludiert oder inline innerhalb der WSDL definiert.

Für die Erstellung von XSDs und WSDLs gibt es zahlreiche Tools, siehe hierzu die Abschnitte „Links„.

XSD in WSDL inkludieren

Hier ein Beispiel (lokale Datei):

	<wsdl:types>
		<xsd:schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="http://www.websale-ag.com/StockUpdateService">
			<xsd:import namespace="http://www.websale-ag.com/xsd/StockUpdateService" schemaLocation="stockupdate.xsd"></xsd:import>
		</xsd:schema>
	</wsdl:types>

Hier ein Beispiel (XSD über URL):

<types>
<xsd:schema>
<xsd:import namespace="http://ohnesei/" schemaLocation="http://localhost:4434/miniwebservice?xsd=1"></xsd:import>
</xsd:schema>
</types>

XSD in WSDL inline definieren

Hier ein Beispiel (mit zwei XSD Inline Defintionen):

   <wsdl:types>
      <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:websale="http://www.websale.net/soap/faults" xmlns:p0="http://www.websale-ag.com/xsd/StockUpdateService" targetNamespace="http://www.websale-ag.com/xsd/StockUpdateService">
         <xsd:complexType name="SoapFault">
            <xsd:sequence>
               <xsd:element name="faultcode" type="xsd:string" />
               <xsd:element name="faultstring" type="xsd:string" />
               <xsd:element name="details" type="p0:Details" />
            </xsd:sequence>
 ...
      </xsd:schema>
      <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:p0="http://www.websale.net/soap/faults" targetNamespace="http://www.websale.net/soap/faults">
         <xsd:simpleType name="Code">
            <xsd:restriction base="xsd:int">
               <xsd:minInclusive value="0" />
            </xsd:restriction>
         </xsd:simpleType>
      </xsd:schema>
...

Aufbau einer WSDL Datei

Die folgende Beschreibung einer WSDL Datei, habe ich bei http://www.torsten-horn.de/techdocs/jee-jax-ws.htm gefunden:

<?xml version="1.0" encoding="UTF-8"?>
<definitions xmlns="http://schemas.xmlsoap.org/wsdl/" WSDL-Namespace
             targetNamespace="...">                   Target-Namespace

  <import> ... </import>                              Importe externer WSDL-Dateien

  <types>                                             Typdeklarationen:
    <xsd:schema> ... </xsd:schema>                      Wahlweise Einbettung von Schema-Informationen
  </types>                                              oder Importe externer Schema-XSD-Dateien

  <message ...><part ... /></message>                 "Messages" sind Parameter und Rückgabewerte (z.B. definiert über XSD)

  <portType ...>                                      "Port Types" entsprechen Java-Interfaces:
    <operation ...>                                     "Operations" entsprechen Java-Methoden:
      <input  ... />                                      Input-Messages (Argumentparameter)
      <output ... />                                      Output-Messages (Rückgabewerte)
      <fault  ... />                                      Fehlernachrichten (z.B. Exceptions)
    </operation>
  </portType>

  <binding ...>                                       "Bindings" sind Verbindungen von "Port Types" zu Protokollen:
    <soap:binding ... />                                Z.B. SOAP-Protokoll über HTTP mit style="document"
    <operation ...>                                     Pro "Operation" Zusatzangaben:
      <soap:operation ... />                              Z.B. soapAction=""
      <input> <soap:body ... /></input>                   Z.B. use="literal"
      <output><soap:body ... /></output>                  Z.B. use="literal"
      <fault ...><soap:fault ... /></fault>               Z.B. use="literal"
    </operation>
  </binding>

  <service ...>                                       "Services" sind Gruppen von "Ports"
    <port ...>                                          "Ports" beschreiben den Zugang zu Diensten
      <soap:address ... />                                Z.B. location="..." (URL des Dienstes)
    </port>
  </service>

</definitions>

 

Links

Tutorials:

http://www.mkyong.com/tutorials/jax-ws-tutorials/

Tools:

freeformatter.com: zahlreiche Online-Tools für JSON, XML, HTML, XSD: Formatter, Validator, Encoder

xmlforasp.net: Online-Umwandlung einer XML-Datei in eine XSD-Datei (XML-Schema)

Microsoft Windows SDK for Windows 7 and .NET Framework 4: enthält u.a. auch Tools, wie xsd.exe oder wsdl.exe

JDKOpenJDK (Java Development Kit): enthält Tools wie wsgen und wsimport

 
Hinterlasse einen Kommentar

Verfasst von - April 13, 2012 in WebServices

 

Schlagwörter: , , , ,

SAP PI: Rest Adapter

SAP PI: Rest Adapter

Ein SAP PI Rest Adapter wird wohl von SAP direkt nicht zur Verfügung gestellt – als Alternative gibt es den kommerziellen Rest Adapter von Advantco.

Im Rahmen Rest Adapter/SAP PI gab es viele Diskussionen, einige waren der Meinung, dass diese Aufabe dem SAP Gateway überlassen werden sollte. Argumente, die durchaus für einen Rest Adapter in SAP PI sprechen sind u.a.:

  • Integration von Cloud- und anderen Web-based-Services
  • Integration von „Mobile Devices“, z.B. Smartphones, Tablets etc.
  • Einfache Integration von SAP(!) und 3rd-Party-Applikationen, die nur Rest-Services zur Verfügung stellen.
    Hier fällt mir SAP Identity Management (SAP IdM) ein, welches eine umfangreiche Rest-Schnittstelle zur Verfügung stellt.

Wie auch immer, von der SAP direkt wird es wohl in nächster Zeit keinen Rest-Adapter geben und es stellt sich die Frage, welche Alternativen gibt es. Natürlich kann man den kommerziellen Rest Adapter von Advantco verwenden. Die Alternative wäre, einen SOAP-Rest-Wrapper zu implementieren, der beispielsweise als Webservice auf dem Rest-Zielsystem die SOAP-Calls in Rest-Calls (und umgekehrt) umwandelt. Ich habe das für SAP Idm bereits erfolgreich umgesetzt. Das ist zwar so, wie wenn man auf einen „platten“ Reifen einen „neuen“ Reifen zieht, aber kostengünstig. Bisher ist mir leider keine kostengünstigere Variante eingefallen.

Links:

 
Hinterlasse einen Kommentar

Verfasst von - März 30, 2012 in SAP, WebServices

 

Schlagwörter: , , ,

Tipp: XAMPP > LAMPP > automatisch sichern

Tipp: XAMPP > LAMPP > automatisch sichern

Die unter Windows Rechner beliebte LAMP (Linux, Apache, MySQL, PHP) Installation – XAMPP, ist auch für Linux Rechner, unter dem Namen „LAMPP“ verfügbar. Nachdem ich mich in der Vergangenheit mit DynDNS und XAMPP meinen Blog publiziert habe, dachte ich mir, geht das auch auf Linux Basis?

Zuerst habe ich das komplette Windows XAMPP-Verzeichnis gezippt und auf Linux kopiert. Danach habe ich LAMPP installiert und das gesicherte XAMPP-Verzeichnis darauf entpackt. Ging alles problemlos:-)

Mit folgenden Skript (/home/juergen/scripts/jkh_lampp_backup.sh) sichere ich zudem automatisch den Inhalt meiner LAMPP Installation über crontab (LAMPP Installation unter /opt/lampp:

/opt/lampp/lampp stop
TARGET="/media/Medion2/Backup/xampp_aspire/`date +%Y%m%d`_lampp.tar.gz"
tar -zcvf /media/Medion2/Backup/xampp_aspire/lampp.tar.gz /opt/lampp/
mv /media/Medion2/Backup/xampp_aspire/lampp.tar.gz $TARGET
/opt/lampp/lampp start
echo "$TARGET succesfully created"

Der Eintrag in der crontab (jeden Donnerstag um 03:00 Uhr):

00 03 * * 4 /home/juergen/scripts/jkh_lampp_backup.sh

Machen wir uns nix vor, XAMPP und damit auch LAMPP sind unsicher, es ist deshalb sinnvoll seine Websites und Inhalte, regelmäßig zu speichern. Bei einem Crash kann man die gesicherte Datei einfach wiederherstellen.

Links:

Download LAMPP

 
Hinterlasse einen Kommentar

Verfasst von - März 14, 2012 in IT, Linux, WebServices

 

Schlagwörter: ,

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: , , ,

JSON Provider erstellen. Part 6: Ressourcen, Sub-Ressourcen


Im letzten Teil ging es um „Ressourcen, Parameter, CRUD, JSON etc.„, in diesem Artikel soll das Thema „Ressourcen“ vertieft werden.

Mit Root- und Sub-Ressourcen, sowie mit Sub-Ressource-Locators ist es möglich einen Rest-Service und dessen Ressourcen in einer Klassen-Hierarchie zu strukturieren.

Root-Ressourcen

Eine Root-Ressource zeichnet sich dadurch aus, dass sie zum einen als POJO (Plain Old Java Object) definiert ist. Die Klasse selbst ist mit @Path annotiert und enthält mindestens eine Methode, die mit @Path, @GET, @PUT, @POST oder @DELETE annotiert ist.

Beispiel:

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import com.sun.jersey.spi.resource.Singleton;

@Singleton
@Path("/printers")
public class ResourcesSubResources {

    // Root -Resource:
    @GET
	@Produces(MediaType.TEXT_PLAIN)
    public String getMyResources() {
    	return "Root-Resource: Method: getMyResources, URI: /printers";
    }
}

Ausgabe:

 

Sub-Ressourcen

Eine Sub-Ressource zeichnet sich dadurch aus, dass es sich entweder um eine Methode handelt, die mit @GET, @POST, @PUT, @DELETE, zusammen mit @Path annotiert ist, oder über Sub-Ressource-Locators delegiert wird.

Beispiel:

package org.jkhofmann.dyndns;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import com.sun.jersey.spi.resource.Singleton;

@Singleton
@Path("/printers")
public class ResourcesSubResources {

    // Root -Resource:
    @GET
	@Produces(MediaType.TEXT_PLAIN)
    public String getMyResources() {
    	return "Root-Resource: Method: getMyResources, URI: /printers";
    }

    // Sub-Resource:
    @GET @Path("/list")
	@Produces(MediaType.TEXT_PLAIN)
    public String getListOfPrinters() {
    	return "Sub-Resource: Method: getListOfPrinters, URI: /printers/list";
    }

    // Sub-Resource:
    @GET @Path("/ids/{printerid}")
	@Produces(MediaType.TEXT_PLAIN)
    public String getPrinter(@PathParam("printerid") String printerId) {
    	return "sub-Resource: Method: getPrinter, URI: /printers/ids/" + printerId;
    }
}

Dazu die entsprechenden Aufrufe in einem Browser:

 

Sub-Ressource-Locators

Man muss nicht alle Root- und Sub-Ressourcen in einer Klasse zusammenfassen. Mit sog. Sub Ressource Locators ist es möglich aus einer Ressource Klasse heraus weitere Ressource Klassen aufzurufen.

Beispiel:

package org.jkhofmann.dyndns;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

import com.sun.jersey.spi.resource.Singleton;

@Singleton
@Path("/printers")
public class ResourcesSubResources {

    // Root -Resource:
    @GET
	@Produces(MediaType.TEXT_PLAIN)
    public String getMyResources() {
    	return "Root-Resource: Method: getMyResources, URI: /printers";
    }
...

    // Sub-Resource-Locator:
    @Path("subresource")
    public SubResource getSubResource() {
        return new SubResource();
    }
}

 

Sub Ressource Klasse:

package org.jkhofmann.dyndns;

import javax.ws.rs.GET;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

public class SubResource {
	@GET
	@Produces(MediaType.TEXT_PLAIN)
    public String getMyResources() {
    	return "Sub-Resource: Method: getMyResources, URI: /printers/subresource with subresource locator";
    }

    @GET
    @Path("{version}")
	@Produces(MediaType.TEXT_PLAIN)
    public String getPrinter(@PathParam("version") String version) {
    	return "sub-Resource: Method: getPrinter, URI: /printers/subresource/{version}" + version;
    }
}

 

Aufruf im Browser:

 

Links

Chapter 2. Overview of JAX-RS 1.1.1

 
Hinterlasse einen Kommentar

Verfasst von - Februar 21, 2012 in IT, WebServices

 
 
Erstelle eine Website wie diese mit WordPress.com
Jetzt starten