|
In Part
1 of this series, you learned how to create a Java
technology-based client for a simple web service using the NetBeans
IDE. Now it's time to go deeper. You will now use what you've
learned to create a Java technology-based client for the eBay
production server. You can do this using the Java
API for XML Web Services (JAX-WS) tools in the Java
SE 6 platform, as well as the official eBay version of the Web Services Definition Language (WSDL, often
pronounced "whiz-dull"):
http://developer.ebay.com/webservices/latest/eBaySvc.wsdl
Note: Any API additions or other enhancements to the Java SE platform specification are subject to review and approval by the JSR 270 Expert Group.
In order to create a web services client, you will follow much the
same procedure you did in Part 1 to create a web services
client in the NetBeans IDE 5.5. But this time, point it to the WSDL located on the eBay
server at http://developer.ebay.com/webservices/latest/eBaySvc.wsdl.
The NetBeans IDE will automatically create all the support files that
you need to access the eBay servers.
First, create a new project called eBayClient, which is a
general Java technology-based application, just as you did in Part
1. Figure 1 shows the New Java Application dialog box in NetBeans
IDE 5.5.
|
Figure 1: The New Java Application Dialog Box Click here for a larger image.
|
|
Right-click the resulting eBayClient project in the main
Projects window, and add a Web Services Client. This brings up the
New Web Service Client dialog box. As the location of the WSDL
file, type the URL of
http://developer.ebay.com/webservices/latest/eBaySvc.wsdl,
and place the generated classes in their own package. This
article will use ebay.apis as the package name.
Figure 2 shows the New Web Service Client dialog box.
|
Figure 2: The New Web Service Client Dialog Box Click here for a larger image.
|
|
The NetBeans IDE will now download the WSDL and use the ws-import
tool to generate and compile the approximately 750 classes that the
eBay client requires. Note: You may get a large number of wsimport
warning messages when these classes are imported. Don't worry about
that; the client will still function normally.
Once all the classes are imported, test your client by using a
sample eBay server using JAX-WS. Next, register with eBay to gain
access to its servers. Then write a Java technology-based client to
call upon the eBay server to get some information.
A Test Server for Your eBay Application
For the purposes of this article, the authors have created a
simple server that emulates eBay so that you can test a client before
moving it onto the full eBay production servers. The test server is
only a small subset of the functionality that the full eBay servers
offer, but it gives you an idea of how to use some of the eBay API
classes.
You can download the full source
code. Following is the portion of the source code that is of primary
interest. Note that you must import all of the classes that were
generated from the WSDL in the package ebay.apis.
import ebay.apis.*;
@WebService(serviceName = "eBayAPIInterfaceService",
portName = "eBayAPI",
endpointInterface = "ebay.apis.EBayAPIInterface",
targetNamespace = "urn:ebay:apis:eBLBaseComponents")
public class EbayServer implements EBayAPIInterface {
private Map items;
public EbayServer() {
items = new HashMap();
ItemType item = new ItemType();
item.setItemID("9720685987");
item.setDescription(
"New Sun Blade 1000 (dual 750Mhz 8MB cache/4GB ram/DVD/2x36)");
item.setTitle(
"Sun Blade 1000 (dual 750Mhz 8MB cache/4GB ram/DVD/2x36)");
AmountType amount = new AmountType();
amount.setValue(1975.99);
amount.setCurrencyID(CurrencyCodeType.USD);
item.setBuyItNowPrice(amount);
PictureDetailsType picDetails = new PictureDetailsType();
picDetails.setGalleryURL(
"http://localhost:8080/EbayServer/images/sun_blade_1000_h400px.jpg");
item.setPictureDetails(picDetails);
items.put(item.getItemID(), item);
items.put("1", item);
...
}
// Remainder of web services code is omitted.
public GetItemResponseType
getItem(GetItemRequestType getItemRequest)
{
GetItemResponseType response = new GetItemResponseType();
ItemType item = items.get(getItemRequest.getItemID());
response.setItem(item);
return response;
}
}
|
This code snippet gives you a brief introduction to some of the more
important classes in the eBay API. First, there is the ItemType
class. This class encapsulates data that represents a single item
that can be or is currently being auctioned. Each auction item in the
test server has a numerical ID, a String title that
appears in the eBay listing catalog, a String
description, and a price associated with it. For this auction, the
authors have decided to forgo the bidding process and use a Buy It
Now price set at USD $1975.99. The authors have also set an image, a
gallery picture that shows the item -- in this case, a Sun Blade 1000
server.
To publish this web service, use the javax.xml.ws.Endpoint
class, as in the simple web service in Part 1:
import javax.xml.ws.Endpoint;
public static void main(String[] args) {
Endpoint.publish("http://localhost:7070/Ebay",
new EbayServer());
}
|
The full server source code creates three such items and plugs them
into a java.util.HashMap. You then activate the
getItem() method and publish it as a web service. Note
that the eBay APIs publish a large number of methods, such as web
services for accessing a user's My eBay page, searching the listing
catalog, and accessing the affiliated PayPal service. However, for
this example, the web service of interest is getItem().
Creating the eBay Client
The eBay APIs are complex, and learning all about them would
require reading a large volume. However, Table 1 shows some of the
basic accessors that you can use with the ItemType
object that this article introduced earlier.
getListingType()
|
Retrieves the auction listing type, such as a Chinese
auction or Dutch
auction. A Chinese auction is a typical auction, in
which the highest bidder wins the item. eBay also allows for a Dutch
auction, among others. |
getPrimaryCategory()
|
|
getSellingStatus().getCurrentPrice()
|
|
getPictureDetails().getGalleryURL()
|
Returns the URL of the gallery image, if one exists, associated
with this eBay auction. |
getCurrency()
|
Returns the currency that this auction uses (for example, USD =
U.S. dollars, AUD = Australian dollars, JPY = Japanese yen).
|
getCountry()
|
Returns the name of country where the seller is located. |
getSeller()
|
Returns the seller's eBay ID. |
getSellingStatus().getHighBidder().getUserID()
|
Return the highest bidder's eBay ID. |
getStartPrice()
|
Returns an AmountType object that represents the
auction item's starting price. |
getSellingStatus().getBidCount()
|
Returns the number of bids that the auction currently has
registered. |
getShippingDetails()
|
Returns an array of ShippingServiceOptionsType
objects that describes the shipping options that the seller
provides to the winner of the auction. |
getHitCount()
|
Returns the number of page views that this eBay item has
received. |
getBuyItNowPrice()
|
Returns an AmountType object that represents the
cost to purchase the item and close the auction. |
getTimeLeft()
|
Returns an object that represents the date and time that the
auction will end. |
Figure 3 shows where most of this data is displayed on the eBay
item auction page.
|
Figure 3: A Sample eBay Item Auction Page With ItemType
Methods Click here for a larger image.
|
|
Communicating With the eBay Production Servers
Before you can communicate with the eBay production servers, you
must hardwire four requester credential codes into your online
application:
- An application ID key
- A developer ID key
- A certificate ID key
- An authentication token
Note that the authentication token is a single-user token. If you
wish to do so, you can use a username and password instead.
The eBay server assigns all four of these codes when you first sign up for
the developer program. For more information, see the section Registering as a Developer
With eBay. Once you have these codes, you can
perform live calls against the eBay server. If you are using the
test server that this article demonstrated earlier, that server
ignores these values.
In the downloadable example that comes with this article, the
actual source code to communicate with the eBay production servers is
located in the callRemoteServer() method of the
SelectItemPanel class. The basic premise is this: You
pass a GetItemRequestTypeobject to the eBay servers, and
you should get a GetItemResponseType object back.
private static final String ebayURL =
"https://api.ebay.com/wsapi?";
// Code is omitted.
// First, create an EBayAPIInterface object and
// cast a copy to a BindingProvider.
EBayAPIInterfaceService svc = new EBayAPIInterfaceService();
EBayAPIInterface port = svc.getEBayAPI();
BindingProvider bp = (BindingProvider)port;
String endpointURL = "";
if (endpointToUse.equals(EBAY_PRODUCTION_SERVER)) {
endpointURL = ebayURL+"callname=GetItem&siteid=0&appid=" +
(String)props.get("appID") +
"&version=479&Routing=new";
// Link in the requester credentials.
List handlerChain = new Vector();
handlerChain.add(new RequesterCredentials());
bp.getBinding().setHandlerChain(handlerChain);
}
// Source code for eBay sandbox and local server is omitted.
bp.getRequestContext().
put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
endpointURL);
GetItemRequestType itemRequest = new GetItemRequestType();
itemRequest.setVersion("479");
itemRequest.setItemID(itemId);
itemRequest.setErrorLanguage("en_US");
GetItemResponseType itemResponse = null;
try {
itemResponse = port.getItem(itemRequest);
} catch (Exception e) {
return null;
}
// Get the ItemType object from the response object.
return itemResponse.getItem();
}
|
This method is not as complex as it may seem. First, you create a
standard EBayAPIInterface object and cast a reference of
that to a BindingProvider. The endpointURL
variable defines the URL location against which you will be making
calls.
The next three lines of code create a handler chain that embeds
the requester credentials in the SOAP header using the binding
provider. You do not have to understand how the handler chain works,
but the handler chain is required when you use SOAP to communicate
with the eBay servers.
Why? The eBay service definition in the WSDL uses the notion of
additional headers that are defined in the binding section in the
WSDL. JAX-WS, however, does not support the use of additional
headers. Hence, you must use the handler to intercept the message and
add the credentials information before you dispatch the message to
the service.
After initialization, you must populate a GetItemRequestType
object with at least these three properties:
Set the API version that you are using, which matches the
version of the WSDL that you downloaded. At the time of this
article's writing, the version number was 479. Set the version
number by using the setVersion() method.
Set the auction item's numerical ID, which will reside on the
server. Set the numerical ID by using the setItemID()
method.
Set the error language for the request using the
itemRequest.setErrorLanguage() method. For this
example, set the language to U.S. English.
Once the eBay production servers have returned a
GetItemResponseType object, extract an
ItemType object by using the
GetItemResponseType.getItem() method. Then use the
methods listed in Table 1 to obtain the pertinent data about the
auction item.
Here is an excerpt of some of the code that you can use to obtain
the auction information:
ItemType item = // GetItemResponseType.getItem()
// Obtain the locations to which the item can ship.
// The ship-to-locations are returned as a List<String>
// that you can iterate through.
List shipToLocations = item.getShipToLocations();
if (shipToLocations != null) {
StringBuffer shipsToString = new StringBuffer();
Iterator regions = shipToLocations.iterator();
while (regions.hasNext()) {
shipsToString.append(regions.next().toString() + " ");
}
shipsTo.setText(shipsToString.toString());
} else {
shipsTo.setText("Error obtaining ship-to-locations");
}
// Identify the seller and get the seller's
// positive feedback percentage.
if (item.getSeller() != null) {
seller.setText(item.getSeller().getUserID());
feedback.setText(
""+item.getSeller().getFeedbackScore().intValue());
} else {
seller.setText("Error obtaining seller info");
feedback.setText("Error obtaining seller info");
}
// Get the location of the item in question.
if (item.getLocation() != null) {
itemLocation.setText(item.getLocation());
} else {
itemLocation.setText("Error obtaining location");
}
|
Note that each time you extract data from the ItemType
class, you first check to see whether the result is null.
This is very important when you work with SOAP web services. If an
auction does not have a specific value set -- for example, if there
have been no bids, so there is no high bidder -- any call to obtain
such information will return null instead of a default
value.
Figure 4 shows a screen capture of the eBay client application in
action.
|
Figure 4: The Sample eBay Client Application Running Against the
Production eBay Servers Click here for a larger image.
|
|
Registering as a Developer With eBay
As mentioned earlier, before you can access the production
servers, you will need to register with the eBay developer program.
Just follow these steps:
Go to the eBay developers' page.
Click the Join Now! button in the upper right corner of the
screen and fill out the required information. Once you do so, eBay
sends a message to the email address you specified in the application
form that gives you the information you need to log in, as well as
your application ID, developer ID, and certificate ID keys.
Log in and create a sandbox eBay user. Note that this is not
a real user on eBay. Instead, it is simply a sandbox user that you
can test against if you need to.
Use the three keys that eBay sent to you by email to generate
an authentication token. You can use these keys in conjunction with
the authentication token.
Perform the self-certification for your application. Once you
do, eBay will send you three new keys that will allow you to access
the production servers. Use these keys to generate a production
token.
You must set these three keys and the production token as
constant Strings in your eBay client application.
Now you are ready to download auction item specifics from the
eBay sandbox or production servers. Feel free to use the application
shown here as a springboard for your own eBay applications.
For More Information
The JAX-WS home page on java.net
The JAX-WS
home page on java.sun.com
Introducing JAX-WS 2.0 With the Java SE 6 Platform, Part 1
The official eBay WSDL:
http://developer.ebay.com/webservices/latest/eBaySvc.wsdl
Download this article's test
server for eBay, which you can use for testing before you
register with eBay.
Download the eBay
client, which you can use to access both the test server and the
production eBay server. However, note that you must register with
eBay first and obtain the three keys and authentication token before
you can access the production servers.
Read documentation on the eBay APIs. Note that the
documentation that you need for JAX-WS projects is based on the web
services-SOAP APIs, not the eBay Java technology SDK. Although the
eBay Java technology page is a good one to investigate if you want
to write a large-scale application for eBay, the API is slightly
different than the WSDL-generated classes that you have generated
for the client in this article.
Download the NetBeans IDE at no cost.
Robert Eckstein has worked with Java technology since its
first release. In a previous life, he was an editor for O'Reilly
Media, Inc. and a programmer for Motorola's cellular technology
division. He has written or edited a number of books, including
Java Swing, Java Enterprise Best Practices, Using
Samba, XML Pocket Reference, and Webmaster in a
Nutshell. In his spare time, he has been known to tinker with
filmmaking and digital photography, as well as collecting vintage
video game consoles.
Rajiv Mordani is a senior engineer at Sun Microsystems. He
is the implementation architect for the web tier. Before this, he
was the implementation architect working on next-generation web
services.
|
Get Java SE 6 Platform Training
|
|