Introducing JAX-WS 2.0 With the Java SE 6 Platform, Part 2

   
By Robert Eckstein and Rajiv Mordani, November 2006  

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.

  1. 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
  2. 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

    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.

Table 1: Useful eBay ItemType Methods
 
 
Method
Description
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()

Returns a CategoryType object that describes the category to which the seller has assigned the item. For example, the Sun Blade 1000 server described earlier in this article may fall under the eBay category Computers & Networking > Networking > Servers > Sun > Enterprise, E Series.

getSellingStatus().getCurrentPrice()

Returns an AmountType

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
 

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:

  1. 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.

  2. Set the auction item's numerical ID, which will reside on the server. Set the numerical ID by using the setItemID() method.

  3. 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
 

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:

  1. Go to the eBay developers' page.

  2. 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.

  3. 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.

  4. 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.

  5. 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.

  6. 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 JSC

  • 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.

About the Authors

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.

Rate and Review
Tell us what you think of the content of this page.
Excellent   Good   Fair   Poor  
Comments:
Your email address (no reply is possible without an address):
Sun Privacy Policy

Note: We are not able to respond to all submitted comments.