Jan 072013
 

Ich hoffe Folgendes hilft dem ein oder anderen beim Schnelleinstieg in die Erstellung eines Contract First RESTful Service unter folgenden Kriterien:

  • JAX-RS (im Speziellen Jersey)
  • Maven-basiert

Contract First bedeutet hier, dass die Maven-Phase “generate-sources” mittels JAXB-Plugin aus XML Schema (XSD) die notwendigen Java-Klassen generiert, welche als Datentypen in einem Service verwendet werden. Daher wähle ich den Contract First Ansatz, um ein Schema zur Schnittstellenabstimmung mit meinen Schnittstellenpartner zu verwenden.

Alle Code-Auszüge findet Ihr in Gänze in meinem Beispielprojekt.

Für die Code-Generierung folge ich Empfehlungen zur Nutzung des jaxb2-maven-plugin in meiner pom.xml:

   1: <build>

   2:   <plugins>

   3:     <plugin>

   4:       <groupId>org.codehaus.mojo</groupId>

   5:       <artifactId>jaxb2-maven-plugin</artifactId>

image

XSD und Binding-Dateien liegen in den separaten Verzeichnissen src/main/xsd und xjb (Default von jaxb2-maven-plugin).

Die XSD enthält die Datentyp-Definitionen (complexType) aus denen das jaxb2-maven-plugin die Datentypklassen generiert. Für die Verwendung als eigenständige Payload für Request bzw. Response eines Service muss die generierte Datentypklasse die JAXB-Annotation @XmlRootElement erhalten. Hierzu muss die XSD zusätzlich zum “xs:complexType” ein “xs:element” unter Verwendung des Typs definieren und…

   1: <xs:element name="businessPartner" type="BusinessPartner"/>

   2: <xs:complexType name="BusinessPartner">

   3:   ...

   4: </xs:complexType>

… das JAXB-Plugin muss eine Binding-Datei (.xjb) vorfinden, welche den Simple-Mode mittels “xjc:simple” aktivitert. Das Binding referenziert in schemaLocation relativ die betreffende XSD.

   1: <?xml version="1.0"?>

   2: <jxb:bindings version="1.0" xmlns:jxb="http://java.sun.com/xml/ns/jaxb" xmlns:xjc="http://java.sun.com/xml/ns/jaxb/xjc" jxb:extensionBindingPrefixes="xjc" xmlns:xs="http://www.w3.org/2001/XMLSchema">

   3:   <jxb:bindings node="/xs:schema" schemaLocation="../xsd/businessPartner.xsd">

   4:     <jxb:globalBindings>

   5:       <xjc:simple />

   6:     </jxb:globalBindings>

   7:   </jxb:bindings>

   8: </jxb:bindings>

Für das JAXB-Plugin ist zu definieren, dass Vendor-spezifische JAXB-Bindings (hier xjc:simple) erlaubt sind:

   1: <plugin>

   2:   ...

   3:   <artifactId>jaxb2-maven-plugin</artifactId>

   4:   <configuration>

   5:      <extension>true</extension>

Da jaxb2-maven-plugin vom Maven-Eclipse-Plugin m2e im Maven-Live-Cycle unterstützt wird, wird unmittelbar Java-Quellcode für die Datentypen generiert, z.B.

   1: ...

   2: @XmlAccessorType(XmlAccessType.FIELD)

   3: @XmlType(name = "BusinessPartner", propOrder = {

   4:     "addresses"

   5: })

   6: @XmlRootElement(name = "businessPartner")

   7: public class BusinessPartner {

   8:

   9:     @XmlElement(name = "address")

  10:     protected List<Address> addresses;

  11:     ...

Der RESTful Service ist für JAX-RS händisch implementiert und referenziert die generierten Datentypen:

   1: @Path("/businessPartner")

   2: @Consumes(MediaType.APPLICATION_JSON)

   3: @Produces(MediaType.APPLICATION_JSON)

   4: public class BusinessPartnerResource {

   5:

   6:     ...

   7:

   8:     @POST

   9:     public void create(BusinessPartner bupa) {

  10:         ...

  11:     }

  12:

  13:     ...

  14:

  15: }

Damit Eclipse WTP den Maven-default der web-Dateistruktur  verwendet, muss in .settings/org.eclipse.wst.common.component das Verzeichnis “src/main/webapp”  statt “WebContent” angegeben werden:

   1: <?xml version="1.0" encoding="UTF-8"?><project-modules id="moduleCoreId" project-version="1.5.0">

   2:     <wb-module deploy-name="testservices">

   3:         <wb-resource deploy-path="/" source-path="/src/main/webapp" tag="defaultRootSource"/>

   4:         ...

   5:     </wb-module>

   6: </project-modules>

Damit steht dem Deployment über die Eclipse-Server-View und anschließendem Test nichts mehr im Weg.

image

Feedback ist willkommen!

 Leave a Reply

(required)

(required)

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>