3.4.2. Creating a WS Implementation Skeleton

Creating a WS implementation with the JAX-WS API in Java basically requires three steps:

  1. Create a Java class which implements the JAX-WS-generated interface of the WS. In our case this interface is provided by the QALL-ME Framework; it is the TermAnnotator interface in the net.sf.qallme.gen.ws.termannotation package.
  2. Add suitable annotations to the class and its web methods for easy and correct deployment in your application server later.
  3. Implement the actual functionality of the WS component by implementing its web methods.
In this section we’ll take care of the first two steps which provide you with an initial skeleton of the new WS component implementation.

The first step in the above list is straightforward: just create a new Java class which implements the TermAnnotator interface as usual. In order to accomplish step two above we need to add appropriate annotations from the JAX-WS API to our WS implementation and its web methods. This may seem a bit difficult at first, however, we have found that just copying and slighly modifying the annotations from the generated interface works flawlessly in most of the cases. You should now copy all annotations from the TermAnnotator interface declaration to your new class. Do the same for the annotations on the annotateTerms method in the interface: just copy all annotations to your own implementation of this method; don’t forget the annotations on the parameters of this method. Your preliminary version of the new WS implementation should look similar to this now:

package com.example;

import javax.jws.WebMethod;
import javax.jws.WebParam;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
import javax.xml.ws.Holder;

import net.sf.qallme.gen.ws.AnnotatedSentence;
import net.sf.qallme.gen.ws.InternalServiceFault;
import net.sf.qallme.gen.ws.termannotation.TermAnnotator;

/**
 * An implementation of the {@link TermAnnotator} WS interface which is based on
 * term dictionaries.
 */
@WebService(name = "TermAnnotator",
			targetNamespace = "http://qallme.sf.net/wsdl/termannotation.wsdl")
@SOAPBinding(parameterStyle = SOAPBinding.ParameterStyle.BARE)
public class DictionaryTermAnnotatorWSProvider implements TermAnnotator {

	/**
	 * Annotates English terms in the given sentence.
	 * 
	 * @param annotatedSentence
	 *            the sentence to annotate with terms
	 * @throws InternalServiceFault
	 *             in case there is any internal problem from which the WS
	 *             cannot recover
	 * @see TermAnnotator#annotateTerms(Holder)
	 */
	@Override
	@WebMethod
	public void annotateTerms(
			@WebParam(name = "AnnotatedSentence",
					targetNamespace = "http://qallme.sf.net/xsd/qallmeshared.xsd",
					mode = WebParam.Mode.INOUT,
					partName = "annotatedSentence")
					Holder<AnnotatedSentence> annotatedSentence)
			throws InternalServiceFault {
		// TODO implement
	}

}

This skeleton could already now be wrapped in a WAR file and successfully be deployed then, however, some parts of the WSDL definition that would be automatically generated for this WS implementation would get default identifiers which makes it a little more difficult later to work with the WS. To avoid this we can add further elements to the WebService annotation of our new class. We will add a name for the service itself and a name for its port; your annotation should now look like this:

@WebService(name = "TermAnnotator",
		serviceName = "TermAnnotatorWS",
		portName = "TermAnnotatorPort",
		targetNamespace = "http://qallme.sf.net/wsdl/termannotation.wsdl") 

We have now finished the skeleton for our new WS component implementation. The previous steps should be very similar for any other new WS implementation that you attempt. The remaining sections of this tutorial all tackle step three of the above list which – as you may have guessed already – is the most substantial part of creating a new WS implementation.