webservice


Since last year I have been working on a REST-version of a webservice to access a handle system server. XML schema is a good way to describe the service interface of such a webservice.

Motivated by the current discussion at the handle mailinglist I finally pushed it to version 0.1 which I would regard rather as a proof of concept and a contribution to this discussion. This schema can be used as a starting point to design a custom REST interface to a handle system server or even as a means to describe a handle site’s data structure and constraints.

Designing the schema I had JAXB java data binding in mind and the possibility to extend handle data types, especially using xml-formatted data in the data section of handle values. I also wanted the representation of handle values in instance documents to be human readable so that clients can easily deal with the semantics of handles.

Have a look at the handle_schema.zip. The schema files are commented und you will also find an example which demonstrates custom datatypes usage.

In simple REST-style webservice situation you sometimes have to model container-item relationships and provide an XML Schema as a means for interface description.
Here is an example how to design the associated XML Schema.

Example of an XML document (container):


<ns2:container xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
xmlns:ns2='http://xml.example.org/schema/container'
xsi:schemaLocation='http://xml.example.org/schema/container container.xsd'>

<ns2:item>
   <ns2:value>A</ns2:value>
</ns2:item>

<ns2:item>
   <ns2:value>B</ns2:value>
</ns2:item>
</ns2:container>

In REST you often want to give access to an item without the container wrapper. One solution is to provide two schema files – one for item and one for container:

container.xsd:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
targetNamespace="http://xml.example.org/schema/container_item"
xmlns:tns="http://xml.example.org/schema/container_item"
elementFormDefault="qualified">

<xsd:include schemalocation="item.xsd"/>

<xsd:element name="container">
   <xsd:complextype>
      <xsd:sequence>
          <xsd:element ref="tns:item" maxoccurs="unbounded"/> 
      </xsd:sequence>
   </xsd:complextype>
</xsd:element>

</xsd:schema>

item.xsd:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
targetNamespace="http://xml.example.org/schema/container_item"
xmlns:tns="http://xml.example.org/schema/container_item"
elementFormDefault="qualified">

<xsd:element name="item" type="tns:itemType">
   <xsd:complextype name="itemType">
      <xsd:sequence>
         <xsd:element name="value" type="xsd:string"/>
      </xsd:sequence>
  </xsd:complextype>
</xsd:element>

</xsd:schema>

It seems to me that there are basically two ways to get started with the examples of the Jersey distribution (see also Java Webservices – Relationship between JAX-WS, JAX-RS, Metro and Jersey) in Glassfish.

First you can use the Glassfish’s update center executing:
$path/updatecenter/bin$ ./updatetool
like described for example in Japod’s blog.
But currently only version 0.4 is available here.

The other way is : download and unzip the newest version of Jersey. In the root directory of the unzipped archive you will find an
ant script, execute it like this:
$path/jersey-0.5-ea$ ant  -f jersey-on-glassfish.xml -Dgf.home=$HOME/bin/glassfish install
with appropriate gf.home property supplied.

If you get an error message similiar to this one:

BUILD FAILED
/home/kostja/Development/jersey/jersey-0.5-ea/jersey-on-glassfish.xml:103: The following error occurred while executing this line:
/home/kostja/Development/jersey/jersey-0.5-ea/jersey-on-glassfish.xml:43: /home/kostja/Development/jersey/jersey-0.5-ea/examples/GlassfishDB not found.

which means some example is missing in the distribution, edit the jersey-on-glassfish.xml file, comment out the matching lines:

     <!-- copy-example example.name="GlassfishDB"/>
     <update-nb-prop nb.prop.file="${gf.home}/jersey/examples/GlassfishDB/nbproject/project.properties"/ -->

Be aware! This procedures will only install the examples and won’t add auto-magically the jersey jars to Glassfish’s runtime classpath. So
you have to take care by yourself to include the jars to the build target, see the provided examples for the jars needed:

glassfish/jersey/examples/SimpleServlet/nbproject/build-impl.xml:

    <target depends="init" name="library-inclusion-in-archive" unless="dist.ear.dir">
        <copy file="${file.reference.activation.jar}" todir="${build.web.dir}/WEB-INF/lib"/>
        <copy file="${file.reference.jsr250-api.jar}" todir="${build.web.dir}/WEB-INF/lib"/>
        <copy file="${file.reference.persistence-api-1.0.jar}" todir="${build.web.dir}/WEB-INF/lib"/>
        <copy file="${file.reference.asm-3.1.jar}" todir="${build.web.dir}/WEB-INF/lib"/>
        <copy file="${file.reference.jsr311-api.jar}" todir="${build.web.dir}/WEB-INF/lib"/>
        <copy file="${file.reference.jersey.jar}" todir="${build.web.dir}/WEB-INF/lib"/>
    </target>

glassfish/jersey/examples/SimpleServlet/nbproject/project.properties:

# some of this properties are set by jersey-on-glassfish.xml
# during installation
ashome.jersey.lib.dir=../../lib
ashome.lib.dir=../../../lib
...
file.reference.jsr250-api.jar=${ashome.jersey.lib.dir}/jsr250-api.jar
...
file.reference.jersey.jar=${ashome.jersey.lib.dir}/jersey.jar
...
javac.classpath=${file.reference.servlet.jar}\:${file.reference.activation.jar}\:${file.reference.jsr250-api.jar}\:
${file.reference.persistence-api-1.0.jar}\:${file.reference.asm-3.1.jar}\:${file.reference.jsr311-api.jar}\:
${file.reference.jersey.jar}

Have you ever wondered about the relationship of different actors within Java’s Webservice Stack? I did. The key to the right answers you may find watching this list of Glassfish projects.

So there seems to be a simple formula (RI = reference implementation):

JAX-WS = JAVA-API( XML-based Webservices, means mainly WSDL/SOAP though REST is possible too )
RI(JAX-WS) = { javax.xml.ws.**.* , core Web services support } = JAX-WS “RI” [is subset of] Metro
Metro = JAX-WS “RI” + WSIT/Tango ( WSIT/Tango provides support for Security, Reliability, Transactions and Interoperability with .NET 3.0 )

JAX-RS = JAVA-API( RESTful Web Services )
RI(JAX-RS) = { javax.ws.rs.**.* } = Jersey

JAX-WS 2.1 along with JAXB 2.1 is integrated in JDK 6 Update 4 release as is JAX-WS in JDK 6. It is part of Java EE 5 as well. To use Metro 1.1 on JDK6 U4, you just have to put the Metro jars in the classpath. Metro is integrated with Glassfish Application Server.
It is possible to run REST Services with JAX-WS using the appropriate Binding like described in RESTful Web Services.

JAX-RS is yet not finally released (see Schedule). If you are using NetBeans IDE 6.0, you do not need to download the Jersey distribution. Instead, install the RESTful Web Services plugin from the Plugin Manager under the Tools menu. Developing RESTful Webservices is much easier here. Implementing RESTful Web Services in Java provides a good start.

If you are looking for the Metro libraries, either get them from GlassFish (webservices*.jar) , or download them from Metro distribution.

Some nice slides for an Metro/Jersey overview : Metro and Jersey.

To use Metro in your application you will need this jars (see also Metro FAQ):

$METRO_HOME/lib/webservices-rt.jar 
$METRO_HOME/lib/webservices-api.jar 
$METRO_HOME/lib/webservices-extra-api.jar 
$METRO_HOME/lib/webservices-extra.jar