|
Contents
|
 |
 |
 |
1. Creating Web Services
1.1 Using Annotations (JSR-181)
1.1.1 Step-By-Step Instructions
1.1.2 Download the Sample
1.2 By Extending WebService
1.2.1 Step-By-Step Instructions
1.2.2 Download the Sample
2. Using Web Service Filters
|
 |
 |
 |
1. Creating Web Services
Creating web services with the WS Toolkit is incredibly easy as the toolkit does most of the work. There are two ways to create web services with the WS Toolkit. The first way, shown in section 1.1, uses Java annotations and the JSR-181 specification to turn Plain Old Java Objects (POJOs) into web services. This is by far the easiest way to create web services because the WS Toolkit WebServicesDeployer will take care of all the hard work. In addition, this approach is best architecturally because the application logic is placed in reusable objects instead of servlet classes.
The second way to create web services, shown in section 1.2, is by extending WebService. This way offers more control over how your web services are deployed but requires more programming to get the service up and running. Both methods are easy to implement and run incredibly fast.
The best way to understand how to create web services is to dive right in and actually create one. In the examples that follow, we will create a contrived web service that emulates the functions of a library. The code is designed to be very simple so don’t expect a complex system with a full implementation of the Dewey Decimal System. This library will allow clients to check books in and out, as well as get a listing of all books in inventory. If a client attempts to check a book in more than once, or check out a book that is not in inventory, then a SOAP Fault will be returned. Otherwise, the request will be processed successfully. The following SOAP messages will represent our library’s interfaces:
| Operation |
Request |
Response |
| Check In |
<soap-env:Envelope xmlns:soap-env="http://www.w3.org/2003/05/soap-envelope">
<soap-env:Body>
<soatoolkits:Request xmlns:soatoolkits="http://soatoolkits.com/schemas/1.0/">
<Book isbn="0969499663">
<Author>Lynda Goldman</Author>
<Title>How to Make a Million Dollar First Impression</Title>
</Book>
</soatoolkits:Request>
</soap-env:Body>
</soap-env:Envelope>
|
<soap-env:Envelope xmlns:soap-env="http://www.w3.org/2003/05/soap-envelope">
<soap-env:Body>
<soatoolkits:Response xmlns:soatoolkits="http://soatoolkits.com/schemas/1.0/"/>
</soap-env:Body>
</soap-env:Envelope>
|
| Check Out |
<soap-env:Envelope xmlns:soap-env="http://www.w3.org/2003/05/soap-envelope">
<soap-env:Body>
<soatoolkits:Request xmlns:soatoolkits="http://soatoolkits.com/schemas/1.0/">
<ISBN>0969499663</ISBN>
</soatoolkits:Request>
</soap-env:Body>
</soap-env:Envelope>
|
<soap-env:Envelope xmlns:soap-env="http://www.w3.org/2003/05/soap-envelope">
<soap-env:Body>
<soatoolkits:Response xmlns:soatoolkits="http://soatoolkits.com/schemas/1.0/">
<Book isbn="0969499663">
<Author>Lynda Goldman</Author>
<Title>How to Make a Million Dollar First Impression</Title>
</Book>
</soatoolkits:Response>
</soap-env:Body>
</soap-env:Envelope>
|
| Get Inventory |
<soap-env:Envelope xmlns:soap-env="http://www.w3.org/2003/05/soap-envelope">
<soap-env:Body>
<soatoolkits:Request xmlns:soatoolkits="http://soatoolkits.com/schemas/1.0/"/>
</soap-env:Body>
</soap-env:Envelope>
|
<soap-env:Envelope xmlns:soap-env="http://www.w3.org/2003/05/soap-envelope">
<soap-env:Body>
<soatoolkits:Response xmlns:soatoolkits="http://soatoolkits.com/schemas/1.0/">
<Inventory>
<Book isbn="0969499663">
<Author>Lynda Goldman</Author>
<Title>How to Make a Million Dollar First Impression</Title>
</Book>
</Inventory>
</soatoolkits:Response>
</soap-env:Body>
</soap-env:Envelope>
|
With these requirements in mind, let’s create our web service using annotations and by extending WebService!
1.1 Using Annotations (JSR-181)
The easiest (and recommended) way to create web services is by using annotations that mark an object as a web service. The WS Toolkit uses JSR-181 annotations to mark a class as a web service and to mark the class’s methods as web operations. Only a very small subset of the JSR-181 specification is used to create a web service so no prior knowledge of the specification is required. Let’s get started and see how easy it is to create web services with the WS Toolkit.
1.1.1 Step-By-Step Instructions
1. The first thing we need to do is create our library. This class will handle checking books in and out, as well as getting the current inventory of books. Create a new class called Library in the package, "com.soatoolkits.samples.annotated". This class will be your new web service:
package com.soatoolkits.samples.annotated;
public class Library
{
}
2. As specified in the requirements above, the library will allow clients to perform 3 functions: checking a book in, checking a book out, and getting the current inventory. Let’s create the 3 methods now:
package com.soatoolkits.samples.annotated;
import com.soatoolkits.soa.ServiceException;
import com.soatoolkits.soa.servlet.SoapFault;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.Set;
public class Library
{
private static ConcurrentMap<String, Book> __inventory = new ConcurrentHashMap<String, Book>();
public static void checkBookIn(final Book book)
{
final String isbn = book.getISBN();
if(__inventory.containsKey(isbn))
{
__inventory.put(book.getISBN(), book);
}
else
{
throw new ServiceException(
SoapFault.CodeValue.SENDER,
"The book is already in inventory. "
+ "We don't need two. "
+ "We're not that fancy of a library.");
}
}
public static Book checkBookOut(final String isbn)
{
final Book book = __inventory.get(isbn);
if(book == null)
{
throw new ServiceException(
SoapFault.CodeValue.SENDER,
"The book is not in inventory.");
}
return(book);
}
public String getInventory()
{
return(toString());
}
public String toString()
{
final StringBuffer asString = new StringBuffer();
final Set<String> isbns = __inventory.keySet();
asString.append("<Inventory>");
for(String isbn : isbns)
{
asString.append(__inventory.get(isbn));
}
asString.append("</Inventory>");
return(asString.toString());
}
}
Note that some methods work with Book objects. To see what a Book object looks like, click here.
3. Now your Library class is complete. At this point, a responsible developer (and I know you are) would take this opportunity to write some good unit tests to verify the Library object is working as expected. Since the logic is coded as a regular Java object, this is quite easy to do and ready-made unit tests can be found here.
4. Now that the functionality has been tested, it’s time to make this Library a web service. The first thing to do is annotate the class as a WebService. This tells the WS Toolkit to deploy this object as a web service when the servlet container starts.
package com.soatoolkits.samples.annotated;
import com.soatoolkits.soa.ServiceException;
import com.soatoolkits.soa.servlet.SoapFault;
import javax.jws.WebService;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.Set;
@WebService
public class Library
{
...
}
5. Based on the sample SOAP messages above, we know we have to set two namespaces, one for the SOAP message itself, and the other for the Request element in the SOAP Body (not only is this good practice but WS-I compliance requires it). To set namespaces for the web service, use the XmlObject annotation. This tells the WS Toolkit that the object will use XML values and should prepare several namespaces.
package com.soatoolkits.samples.annotated;
import com.soatoolkits.soa.ServiceException;
import com.soatoolkits.soa.servlet.SoapFault;
import com.soatoolkits.xml.XmlObject
import javax.jws.WebService;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.Set;
@WebService
@XmlObject(namespaces = {
"env='http://www.w3.org/2003/05/soap-envelope'",
"soatoolkits='http://soatoolkits.com/schemas/1.0/'"
})
public class Library
{
...
}
6. Next, we need to tell the WS Toolkit which methods make up the Library’s public interface. This done using the WebMethod annotation. This annotation simply tells the WS Toolkit that the method should be made available to receive SOAP requests.
package com.soatoolkits.samples.annotated;
import com.soatoolkits.soa.ServiceException;
import com.soatoolkits.soa.servlet.SoapFault;
import com.soatoolkits.xml.XmlObject
import javax.jws.WebMethod;
import javax.jws.WebService;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.Set;
@WebService
@XmlObject(namespaces = {
"env='http://www.w3.org/2003/05/soap-envelope'",
"soatoolkits='http://soatoolkits.com/schemas/1.0/'"
})
public class Library
{
@WebMethod
public static void checkBookIn(final Book book)
{
...
}
@WebMethod
public static Book checkBookOut(final String isbn)
{
...
}
@WebMethod
public String getInventory()
{
...
}
...
}
7. Finally, we need to tell the WS Toolkit how to get the methods’ values from the SOAP request. This is done using the XmlParam annotation that will specify a full XPath 2.0 expression to the value in the SOAP request.
package com.soatoolkits.samples.annotated;
import com.soatoolkits.soa.ServiceException;
import com.soatoolkits.soa.servlet.SoapFault;
import com.soatoolkits.xml.XmlObject
import com.soatoolkits.xml.XmlParam
import javax.jws.WebMethod;
import javax.jws.WebService;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.Set;
@WebService
@XmlObject(namespaces = {
"env='http://www.w3.org/2003/05/soap-envelope'",
"soatoolkits='http://soatoolkits.com/schemas/1.0/'"
})
public class Library
{
@WebMethod
public static void checkBookIn(
@XmlParam(xpath = "/env:Envelope/env:Body/soatoolkits:Request/Book") final Book book)
{
...
}
@WebMethod
public static Book checkBookOut(
@XmlParam(xpath = "/env:Envelope/env:Body/soatoolkits:Request/ISBN") final String isbn)
{
...
}
@WebMethod
public String getInventory()
{
...
}
...
}
That’s it; we’re done! Our web service is complete and ready to be deployed. Your completed class should look like this. To deploy the web service, simply create a web.xml file for the web application that includes the WebServicesDeployer. The WebServicesDeployer will automatically discover and deploy all web services found in your web application. It does this by searching through all class files in your web application’s classes folder. Then, when a class annotated as a WebService is found, all its WebMethods are deployed using the pattern, "http://your.domain.com/$webapp-name/$class-name/$method-name". For our example above, assuming Tomcat is your servlet container and the web application is named "samples", our Library service would reside under "tomcat/webapps/samples/WEB-INF/classes/com/soatoolkits/samples/annotated/Library.class". When the WebServicesDeployer finds the Library web service, its WebMethods will be deployed as:
http://your.domain.com/samples/Library/checkBookIn
http://your.domain.com/samples/Library/checkBookOut
http://your.domain.com/samples/Library/getInventory
The WebServicesDeployer takes numerous optional parameters that control its and information on those parameters may be found here.
Full deployment instructions for Tomcat are as follows:
1. Create a folder under "tomcat/webapps/" called "samples".
2. Create a new folder under "tomcat/webapps/" called "WEB-INF".
3. Copy this web.xml to "tomcat/webapps/samples/WEB-INF/".
4. Create a new folder under "tomcat/webapps/samples/WEB-INF/" called "lib".
5. Copy soatoolkits.jar, jsr181.jar to "tomcat/webapps/samples/WEB-INF/lib/"
6. Create the folder structure under "tomcat/webapps/samples/WEB-INF/" with the path "classes/com/soatoolkits/samples/annotated"
7. Build Library.class and Book.class.
8. Copy Library.class and Book.class to "tomcat/webapps/samples/WEB-INF/classes/com/soatoolkits/samples/annotated/"
9. Start tomcat and watch the console. The WebServicesDeployer will display information as it locates and deploys the web service.
Once deployed, we can test our new service. A handy JUnit test file is included here. This file will send actual SOAP messages over HTTP to your new web service.
1.1.2 Download the Sample
The complete example above can be found here. To deploy the example, assuming Tomcat is your servlet container, unzip the file under "tomcat/webapps/".
1.2 By Extending WebService
TODO
1.2.1 Step-By-Step Instructions
TODO
1.2.2 Download the Sample
TODO
2. Using Web Service Filters
TODO
|
|
|
|