Programming Advanced Features of WebLogic Web Services Using JAX-WS
Programming RESTful Web Services
The following sections describe how to use callbacks to notify clients of events:
- Overview of RESTful Web Services
- Programming RESTful Web Services: Main Steps
- Programming Guidelines for the RESTful Web Service
- Accessing the RESTful Web Service from a Client
Overview of RESTful Web Services
Representational State Transfer (REST) describes any simple interface that transmits data over a standardized interface (such as HTTP) without an additional messaging layer, such as SOAP. REST provides a set of design rules for creating stateless services that are viewed as resources, or sources of specific information, and can be identified by their unique URIs. A client accesses the resource using the URI and a representation of the resource is returned. The client is said to transfer state with each new resource representation.
You build RESTful endpoints using the invoke() method of the javax.xml.ws.Provider<T> interface. The Provider interface provides a dynamic alternative to building an service endpoint interface (SEI).
Programming RESTful Web Services: Main Steps
The procedure in this section describes how to program and compile the JWS file required to implement the RESTful Web SErvice. The procedure shows how to create the JWS file from scratch; if you want to update an existing JWS file, you can also use this procedure as a guide.
It is assumed that you have set up an Ant-based development environment and that you have a working build.xml file to which you can add targets for running the jwsc Ant task and deploying the Web Services. For more information, see Getting Started With WebLogic Web Services Using JAX-WS.
Table 9-1 Steps to Program RESTful Web Services # Step Description 1 Create a new JWS file, or update an existing one, that implements the RESTful Web Service. Use your favorite IDE or text editor. See Programming Guidelines for the RESTful Web Service. 2 Update your build.xml file to include a call to the jwsc Ant task to compile the RESTful JWS file into a Web Service. For example: <jwsc srcdir="." destdir="output/restEar">
<jws file="NearbyCity.java" type="JAXWS"/>
</jwsc> For more information, see “Running the jwsc WebLogic Web Services Ant Task” in Getting Started With the WebLogic Web Services Using JAX-WS.3 Run the Ant target to build the RESTful Web Service. For example: prompt> ant build-rest4 Deploy the RESTful Web Service as usual. See “Deploying and Undeploying WebLogic Web Services” in Programming WebLogic Web Services Using JAX-WS. 5 Access the RESTful Web Service from your Web Service client. See Accessing the RESTful Web Service from a Client.
Programming Guidelines for the RESTful Web Service
The following example shows a simple JWS file that implements a RESTful Web Service; see the explanation after the example for coding guidelines that correspond to the Java code in bold.
package examples.webservices.jaxws.rest;
import javax.xml.ws.WebServiceProvider;
import javax.xml.ws.BindingType;
import javax.xml.ws.Provider;
import javax.xml.ws.WebServiceContext;
import javax.xml.ws.handler.MessageContext;
import javax.xml.ws.http.HTTPBinding;
import javax.xml.ws.http.HTTPException;
import javax.xml.transform.Source;
import javax.xml.transform.stream.StreamSource;
import javax.annotation.Resource;
import java.io.ByteArrayInputStream;
import java.util.StringTokenizer;@WebServiceProvider(
targetNamespace="http://example.org",
serviceName = "NearbyCityService")
@BindingType(value = HTTPBinding.HTTP_BINDING)
public class NearbyCity implements Provider<Source> {
@Resource(type=Object.class)
protected WebServiceContext wsContext;
public Source invoke(Source source) {
try {
MessageContext messageContext = wsContext.getMessageContext();
String query =
(String)messageContext.get(MessageContext.QUERY_STRING);
if (query != null && query.contains("lat=") &&
query.contains("long=")) {
return createSource(query);
} else {System.err.println("Query String = "+query);
throw new HTTPException(404);
}
} catch(Exception e) {
e.printStackTrace();
throw new HTTPException(500);
}
}
private Source createSource(String str) throws Exception {
StringTokenizer st = new StringTokenizer(str, "=&/");
String latLong = st.nextToken();
double latitude = Double.parseDouble(st.nextToken());
latLong = st.nextToken();
double longitude = Double.parseDouble(st.nextToken());
City nearby = City.findNearBy(latitude, longitude);
String body = nearby.toXML();
return new StreamSource(new ByteArrayInputStream(body.getBytes()));
}static class City {
String city;
String state;
double latitude;
double longitude;City(String city, double lati, double longi, String st) {
this.city = city;
this.state = st;
this.latitude = lati;
this.longitude = longi;
}
double distance(double lati, double longi) {
return Math.sqrt((lati-this.latitude)*(lati-this.latitude) +
(longi-this.longitude)*(longi-this.longitude)) ;
}
static final City[] cities = {
new City("San Francisco",37.7749295,-122.4194155,"CA"),
new City("Columbus",39.9611755,-82.9987942,"OH"),
new City("Indianapolis",39.7683765,-86.1580423,"IN"),
new City("Jacksonville",30.3321838,-81.655651,"FL"),
new City("San Jose",37.3393857,-121.8949555,"CA"),
new City("Detroit",42.331427,-83.0457538,"MI"),
new City("Dallas",32.7830556,-96.8066667,"TX"),
new City("San Diego",32.7153292,-117.1572551,"CA"),
new City("San Antonio",29.4241219,-98.4936282,"TX"),
new City("Phoenix",33.4483771,-112.0740373,"AZ"),
new City("Philadelphia",39.952335,-75.163789,"PA"),
new City("Houston",29.7632836,-95.3632715,"TX"),
new City("Chicago",41.850033,-87.6500523,"IL"),
new City("Los Angeles",34.0522342,-118.2436849,"CA"),
new City("New York",40.7142691,-74.0059729,"NY")};
static City findNearBy(double lati, double longi) {
int n = 0;
for (int i = 1; i < cities.length; i++) {
if (cities[i].distance(lati, longi) <
cities[n].distance(lati, longi)) {
n = i;
}
}
return cities[n];
}
public String toXML() {
return "<ns:NearbyCity xmlns:ns=\"http://example.org\"><City>"
+this.city+"</City><State>"+ this.state+"</State><Lat>"
+this.latitude +
"</Lat><Lng>"+this.longitude+"</Lng></ns:NearbyCity>";
}
}
}Follow these guidelines when programming the JWS file that implements the RESTful Web Service. Code snippets of the guidelines are shown in bold in the preceding example.
- Import the packages required to implement the RESTful Web Service.
import javax.xml.ws.WebServiceProvider;
import javax.xml.ws.BindingType;
import javax.xml.ws.Provider;- Annotate the Provider implementation class and set the binding type to HTTP.
@WebServiceProvider(
targetNamespace="http://example.org",
serviceName = "NearbyCityService")
@BindingType(value = HTTPBinding.HTTP_BINDING)- Implement the invoke() method of the Provider interface.
public class NearbyCity implements Provider<Source> {
@Resource(type=Object.class)
protected WebServiceContext wsContext;
public Source invoke(Source source) {
...
}- Get the request string using the QUERY_STRING field in the javax.xml.ws.handler.MessageContext for processing. The query string is then passed to the createSource() method that returns the city, state, longitude, and latitude that is closest to the specified values.
String query =
(String)messageContext.get(MessageContext.QUERY_STRING);
.
.
.
return createSource(query);
Accessing the RESTful Web Service from a Client
To access a RESTful Web Service from a Web Service client, use the resource URI. For example:
http://localhost:7001/NearbyCity/NearbyCityService?lat=35&long=-120In this example, you set the latitude (lat) and longitude (long) values, as required, to access the required resource.