Table of Contents
This chapter describes various ways to implement JAX-RPC web services.
Implementing a JEUS JAX-RPC web service requires the writing and compiling of Java code, which is a web service back-end component. JEUS JAX-RPC supports two types of web service back-end components, Java class and EJB.
The following procedures describe the main steps for implementing a JEUS JAX-RPC web service.
Write the Java code for the back-end components that make up the web service.
To process a SOAP request or response information or directly access the SOAP attachments, create SOAP message handlers and handler chains.
Compile the Java code.
Creating a web service from a Java class is the simplest way of implementing a JAX-RPC web service. Let's start out with a simple example.
To create a Java web service, a service endpoint interface (SEI) and implementation class must be defined. SEI defines the Java class methods to be exposed as web service operations. The implementation class contains the actual implementation of the SEI. The following SEI defines the web service operations, echoString and echoString_double.
package jeustest.webservices.java2wsdl.doclit; public interface Echo extends java.rmi.Remote { public String echoString(String arg11) throws java.rmi.RemoteException; public String echoString_double(String arg1, String arg2) throws java.rmi.RemoteException; }
As mentioned already, SEI specifies which web service operations are exposed for external access through the SOAP protocol. An SEI should directly or indirectly extend the java.rmi.Remote interface and each method should throw a java.rmi.RemoteException exception. After the web service operations are defined, their actual logic must be implemented in the implementation class.
The following is an example of an implementation class.
package jeustest.webservices.java2wsdl.doclit; public class EchoImpl implements Echo { public String echoString(String input0) throws java.rmi.RemoteException { return input0; } public String echoString_double(String input0, String input1) throws java.rmi.RemoteException { return input0+input1; } }
The implementation class implements the SEI. It is instantiated and executed on the JavaEE server, and runs as a web service at runtime.
The following principles must be followed when creating a back-end Java web service.
Define Service Endpoint Interface.
Define a public class.
Define a default constructor with no arguments.
Define the Java class methods that are exported as public and non-static.
Implement thread-safe Java code.
Do not use any overloaded methods for interoperability.
When aforementioned principles have been satisfied, create a web service by using the following steps.
Implement a Java class that contains the web service methods.
Implement an SEI by defining the methods to be exposed as web service operations.
When developing a JavaEE web service, EJB may be more complex than the Java web service programming model, but it provides more functions. The complexity is due to the automatic transaction management.
A solid understanding of EJBs is required to implement an EJB web service. This section may be skipped if EJB will not be used for implementing web services.
A stateless session EJB can also be exported as a web service, and it also requires an SEI.
The following SEI (HelloIF.java) defines a web service operation called sayHello(String).
[Example 20.1] << HelloIF.java >>
package helloejb; import java.rmi.Remote; import java.rmi.RemoteException; public interface HelloIF extends Remote { public String sayHello(String s) throws RemoteException; }
An SEI defines the web service operations to be exposed for
external access through the SOAP protocol. An SEI should directly or
indirectly extend the java.rmi.Remote interface, and each method must
throw the java.rmi.RemoteException exception. After the web service
operations are defined, the actual logic must be implemented in the
implementation class. In the following example, an EJB is used as the
implementation class.
The following is an example of a remote interface class.
[Example 20.2] << Hello.java >>
package helloejb; import javax.ejb.EJBObject; import java.rmi.RemoteException; public interface Hello extends EJBObject { String sayHello(String s) throws RemoteException; }
The following is the home interface class.
[Example 20.3] << HelloHome.java >>
package helloejb; import java.io.Serializable; import java.rmi.RemoteException; import javax.ejb.CreateException; import javax.ejb.EJBHome; public interface HelloHome extends EJBHome { Hello create() throws RemoteException, CreateException; }
The following is the EJB endpoint bean class that contains the implementation of the session bean.
[Example 20.4] << HelloEJB >>
package helloejb; import java.rmi.RemoteException; import javax.ejb.SessionBean; import javax.ejb.SessionContext; import java.lang.*; public class HelloEJB implements SessionBean { public HelloEJB() {} public String sayHello(String s) throws RemoteException { try { Thread.currentThread().sleep(500); } catch (Exception ex) { throw new RemoteException("" + ex); } return "Hello World!" + s; } public void ejbCreate() {} public void ejbRemove() throws RemoteException {} public void setSessionContext(SessionContext sc) {} public void ejbActivate() {} public void ejbPassivate() {} }
If the web service operation is configured as 'one-way', the EJB method's return type must be 'void'. Otherwise, developing a stateless session EJB web service is not different from developing a general EJB.
When the aforementioned principles have been satisfied, create a web service in the following steps.
Implement an EJB that contains web service methods.
Implement an SEI that defines the methods to be exposed as web service operations.
Most of this guide assumes that a user is implementing a web service by writing the backend component first. However, an existing WSDL can also be used to create the implementation code. In this case, the wsdl2java Ant task can be used to generate a web service template. The Ant task uses an existing WSDL file, or one created by the user.
The following example shows a sample build file used to execute the wsdl2java Ant task.
[Example 20.5] << build.xml >>
<target name="do-package-war"> ... <antcall target="wsdl2java"> <param name="wsdl2java.option" value="-import:server -d ${build.war.dir}/WEB-INF/classes -package sample.datahandleronly.service -outputmapping ${build.war.dir}/WEB-INF/SubmitBookService-mapping.xml -compile ${src.web}/WEB-INF/wsdl/SubmitBookService.wsdl" /> </antcall> ... </target>
The following command can be used to generate a web service source code template.
prompt>ant do-package-war
The service interface implementation can be created by referring to '"20.2. Implementing a Web Service from a Java Class"' and '"20.3. Implementing a Web Service from an EJB"'.
For further information about the wsdl2java task, refer to JEUS Reference Book. "4.10. wsdl2java" and JEUS Reference Book. "5.5.2. wsdl2java".
A SOAP message is usually included in the SOAP body. However, it is sent as a SOAP attachment when a specific Java type is used as the parameter or return value of a method that implements the web service operation.
JEUS web services define the Java data types and their corresponding MIME types in a SAAJ(SOAP with Attachments API for Java) as in the following.
[Table 20.1] Required Mappings: Java to MIME
Java Type | MIME Type |
---|---|
java.awt.Image | image/gif or image/jpeg |
java.lang.String | text/plain |
javax.mail.internet.MimeMultipart | multipart/* |
javax.xml.transform.Source | text/xml or application/xml |
For each MIME type, JAX-RPC endpoint stub marshals and
unmarshals the corresponding Java type to and from an encoded data stream.
For more information, refer to "Chapter 23. Creating SOAP Message Handler of JAX-RPC Web Service".