This is the fourth tutorial of Nano tutorial series, in this tutorial, I will show you how to integrate Nano with eBay Shopping Web Service, if you are not familiar with this service, just have a quick review on its official site, basically, eBay Shopping service allows you to search for eBay items, products and reviews, user info, and popular items and searches. In previous tutorials, I showed you how to integrate Nano with SOAP based services, while in this tutorial, I will show you how to interate Nano with XML based service, the eBay Shopping service just supports XML message format.
Depends on the network speed, you may need to wait a few moments to let the code generator download the wsdl and generate code, you may also download the wsdl and run the code generator with a local wsdl.
A few comments about the codegen options:
The code generator will throw many warnings, say that the wsdl violates some schema rule, just ignore them, it’s ok as long as the final code is generated correctly.
I have added a special -ebayshopping codegen option, this is because eBay Shopping service needs a per-call operation name HTTP header(eBay Finding service also needs a similar but different header), I added this special flag in the code generator to let it generate the header for me, since I don’t want to add this header everytime I call an eBay Shopping service, so this is just a special flag for eBay Shopping services and for demo only, or a hidden feature, not a generic codegen option.
By default, the code generator will derive package name from target namespace in wsdl, if necessary, you can override package name with -p option.
The generator will generate both SOAP and XML clients for us, in the client sub-folder.
Step 2 - Create New Android Project, Add Nano Library and Generated Proxy into Your Project
Create a simple Android project called HelloeBayShopping in eclipse(or other IDE you prefer), then:
Now build the project to ensure it can build successfully.
The code generation will generate both SOAP and XML based interfaces from eBay Shopping wsdl for us,
since we will use XML based interface in this tutorial, you may now review the generated eBay Shopping service XML interface to learn what kinds of functions are provided by eBay Shopping service, and what kinds of parameters are needed to call the service, the interface is posted below:
// Generated by wsdl compiler for android/java// DO NOT CHANGE!packageebay.apis.eblbasecomponents.client;importcom.leansoft.nano.ws.XMLServiceCallback;importcom.leansoft.nano.ws.NanoXMLClient;importebay.apis.eblbasecomponents.GetSingleItemResponseType;importebay.apis.eblbasecomponents.GetShippingCostsResponseType;importebay.apis.eblbasecomponents.GetCategoryInfoResponseType;importebay.apis.eblbasecomponents.GeteBayTimeRequestType;importebay.apis.eblbasecomponents.GetCategoryInfoRequestType;importebay.apis.eblbasecomponents.GetUserProfileRequestType;importebay.apis.eblbasecomponents.GetUserProfileResponseType;importebay.apis.eblbasecomponents.GetSingleItemRequestType;importebay.apis.eblbasecomponents.FindPopularSearchesRequestType;importebay.apis.eblbasecomponents.FindHalfProductsResponseType;importebay.apis.eblbasecomponents.FindPopularItemsRequestType;importebay.apis.eblbasecomponents.FindReviewsAndGuidesRequestType;importebay.apis.eblbasecomponents.FindPopularSearchesResponseType;importebay.apis.eblbasecomponents.FindProductsResponseType;importebay.apis.eblbasecomponents.GeteBayTimeResponseType;importebay.apis.eblbasecomponents.GetMultipleItemsResponseType;importebay.apis.eblbasecomponents.GetShippingCostsRequestType;importebay.apis.eblbasecomponents.GetItemStatusResponseType;importebay.apis.eblbasecomponents.FindPopularItemsResponseType;importebay.apis.eblbasecomponents.GetMultipleItemsRequestType;importebay.apis.eblbasecomponents.FindProductsRequestType;importebay.apis.eblbasecomponents.FindReviewsAndGuidesResponseType;importebay.apis.eblbasecomponents.FindHalfProductsRequestType;importebay.apis.eblbasecomponents.GetItemStatusRequestType;/** This class is the XML client to the ShoppingInterface Web Service.*/publicclassShoppingInterface_XMLClientextendsNanoXMLClient{/** public method */publicvoidfindHalfProducts(FindHalfProductsRequestTyperequestObject,XMLServiceCallback<FindHalfProductsResponseType>serviceCallback){super.getAsyncHttpClient().addHeader("X-EBAY-API-CALL-NAME","FindHalfProducts");super.invoke(requestObject,serviceCallback,FindHalfProductsResponseType.class);}/** public method */publicvoidfindPopularItems(FindPopularItemsRequestTyperequestObject,XMLServiceCallback<FindPopularItemsResponseType>serviceCallback){super.getAsyncHttpClient().addHeader("X-EBAY-API-CALL-NAME","FindPopularItems");super.invoke(requestObject,serviceCallback,FindPopularItemsResponseType.class);}/** public method */publicvoidfindPopularSearches(FindPopularSearchesRequestTyperequestObject,XMLServiceCallback<FindPopularSearchesResponseType>serviceCallback){super.getAsyncHttpClient().addHeader("X-EBAY-API-CALL-NAME","FindPopularSearches");super.invoke(requestObject,serviceCallback,FindPopularSearchesResponseType.class);}/** public method */publicvoidfindProducts(FindProductsRequestTyperequestObject,XMLServiceCallback<FindProductsResponseType>serviceCallback){super.getAsyncHttpClient().addHeader("X-EBAY-API-CALL-NAME","FindProducts");super.invoke(requestObject,serviceCallback,FindProductsResponseType.class);}/** public method */publicvoidfindReviewsAndGuides(FindReviewsAndGuidesRequestTyperequestObject,XMLServiceCallback<FindReviewsAndGuidesResponseType>serviceCallback){super.getAsyncHttpClient().addHeader("X-EBAY-API-CALL-NAME","FindReviewsAndGuides");super.invoke(requestObject,serviceCallback,FindReviewsAndGuidesResponseType.class);}/** public method */publicvoidgetCategoryInfo(GetCategoryInfoRequestTyperequestObject,XMLServiceCallback<GetCategoryInfoResponseType>serviceCallback){super.getAsyncHttpClient().addHeader("X-EBAY-API-CALL-NAME","GetCategoryInfo");super.invoke(requestObject,serviceCallback,GetCategoryInfoResponseType.class);}/** public method */publicvoidgetItemStatus(GetItemStatusRequestTyperequestObject,XMLServiceCallback<GetItemStatusResponseType>serviceCallback){super.getAsyncHttpClient().addHeader("X-EBAY-API-CALL-NAME","GetItemStatus");super.invoke(requestObject,serviceCallback,GetItemStatusResponseType.class);}/** public method */publicvoidgetMultipleItems(GetMultipleItemsRequestTyperequestObject,XMLServiceCallback<GetMultipleItemsResponseType>serviceCallback){super.getAsyncHttpClient().addHeader("X-EBAY-API-CALL-NAME","GetMultipleItems");super.invoke(requestObject,serviceCallback,GetMultipleItemsResponseType.class);}/** public method */publicvoidgetShippingCosts(GetShippingCostsRequestTyperequestObject,XMLServiceCallback<GetShippingCostsResponseType>serviceCallback){super.getAsyncHttpClient().addHeader("X-EBAY-API-CALL-NAME","GetShippingCosts");super.invoke(requestObject,serviceCallback,GetShippingCostsResponseType.class);}/** public method */publicvoidgetSingleItem(GetSingleItemRequestTyperequestObject,XMLServiceCallback<GetSingleItemResponseType>serviceCallback){super.getAsyncHttpClient().addHeader("X-EBAY-API-CALL-NAME","GetSingleItem");super.invoke(requestObject,serviceCallback,GetSingleItemResponseType.class);}/** public method */publicvoidgetUserProfile(GetUserProfileRequestTyperequestObject,XMLServiceCallback<GetUserProfileResponseType>serviceCallback){super.getAsyncHttpClient().addHeader("X-EBAY-API-CALL-NAME","GetUserProfile");super.invoke(requestObject,serviceCallback,GetUserProfileResponseType.class);}/** public method */publicvoidgeteBayTime(GeteBayTimeRequestTyperequestObject,XMLServiceCallback<GeteBayTimeResponseType>serviceCallback){super.getAsyncHttpClient().addHeader("X-EBAY-API-CALL-NAME","GeteBayTime");super.invoke(requestObject,serviceCallback,GeteBayTimeResponseType.class);}}
All the methods in the interface follow same calling paradigm - you call the service with required request object and a callback object implementing interface XMLServiceCallback.
You may also compare the XML interface with the SOAP interface, they are almost similar, except that SOAP interface will give you an additional SOAPFault object in the failure callback(in SOAPServiceCallback), this is obvious, since XML based service has no concept of SOAPFault, usually, the response error is returned as response resident error(RRE) in the XML response message.
Step 3 - Implement Appliction Logic and UI, Call Proxy to Invoke Web Service as Needed.
packagecom.ebay.service.shopping;importebay.apis.eblbasecomponents.client.ShoppingInterface_XMLClient;publicclassShoppingServiceClient{// productionpublicstaticStringeBayShoppingServiceURLString="http://open.api.ebay.com/shopping?";// sandbox//public static final String eBayShoppingServiceURLString = "http://open.api.sandbox.ebay.com/shopping";publicstaticStringeBayAppId="YOUR APPID HERE";publicstaticStringtargetAPIVersion="809";/** for site id list, see http://developer.ebay.com/DevZone/shopping/docs/CallRef/types/SiteCodeType.html */publicstaticStringtargetSiteid="0";privatestaticvolatileShoppingInterface_XMLClientclient=null;publicstaticShoppingInterface_XMLClientgetSharedClient(){if(client==null){synchronized(ShoppingServiceClient.class){if(client==null){client=newShoppingInterface_XMLClient();client.setEndpointUrl(eBayShoppingServiceURLString);client.getAsyncHttpClient().addHeader("X-EBAY-API-APP-ID",eBayAppId);client.getAsyncHttpClient().addHeader("X-EBAY-API-REQUEST-ENCODING","XML");client.getAsyncHttpClient().addHeader("X-EBAY-API-VERSION",targetAPIVersion);client.getAsyncHttpClient().addHeader("X-EBAY-API-SITE-ID",targetSiteid);}}}returnclient;}}
Like eBay Finding service, the eBay Shopping service needs a few HTTP headers set to work, let me give more comments:
eBay Shopping service needs to set a few HTTP headers to work, for a list of required headers, please refer to doc here.
One mandatory header for eBay Shopping service is eBayAppId, you need to register on eBay developer site as an eBay developer then get this id, before your can run this demo, you must fill in your own eBayAppId in the shared client.
Another mandatory header for eBay Shopping service is targetAPIVersion, aka the API version you want to use, usually, you use the latest one, at the time of this writing, the latest version is 809, you may update this according to your real needs.
We also set X-EBAY-API-REQUEST-ENCODING to XML, indicating we want to call XML service supported by eBay Shopping service.
Now the UI part and application logic, for this hello world like sample, we just need a EditText for keyword input and Button to trigger eBay search by invoking listening method onClick which will indirectly call eBay Shopping service through the proxy, fairly simple, see the full application logic in MainActivity class below:
packagecom.leansoft.nano.sample;importcom.ebay.service.shopping.ShoppingServiceClient;importcom.leansoft.nano.ws.XMLServiceCallback;importebay.apis.eblbasecomponents.AckCodeType;importebay.apis.eblbasecomponents.ErrorType;importebay.apis.eblbasecomponents.FindPopularItemsRequestType;importebay.apis.eblbasecomponents.FindPopularItemsResponseType;importebay.apis.eblbasecomponents.SimpleItemType;importebay.apis.eblbasecomponents.client.ShoppingInterface_XMLClient;importandroid.os.Bundle;importandroid.app.Activity;importandroid.view.View;importandroid.view.View.OnClickListener;importandroid.widget.Button;importandroid.widget.EditText;importandroid.widget.Toast;publicclassMainActivityextendsActivity{@OverrideprotectedvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.activity_main);ButtonsearchButton=(Button)this.findViewById(R.id.search_button);searchButton.setOnClickListener(newOnClickListener(){@OverridepublicvoidonClick(Viewarg0){// Get shared clientShoppingInterface_XMLClientclient=ShoppingServiceClient.getSharedClient();client.setDebug(true);// enable xml message logging// Build request objectFindPopularItemsRequestTyperequest=newFindPopularItemsRequestType();Stringkeywords=((EditText)findViewById(R.id.keyword_input)).getText().toString();request.queryKeywords=keywords;// only need one item for demorequest.maxEntries=1;// make API call with registered callbacksclient.findPopularItems(request,newXMLServiceCallback<FindPopularItemsResponseType>(){@OverridepublicvoidonSuccess(FindPopularItemsResponseTyperesponseObject){if(AckCodeType.SUCCESS==responseObject.ack){if(responseObject.itemArray.item.size()>0){// show the title of first found itemSimpleItemTypeitem=responseObject.itemArray.item.get(0);Toast.makeText(MainActivity.this,item.title,Toast.LENGTH_LONG).show();}else{// no resultToast.makeText(MainActivity.this,"No result",Toast.LENGTH_LONG).show();}}else{// response resident errorErrorTypeerror=responseObject.errors.get(0);Toast.makeText(MainActivity.this,error.shortMessage,Toast.LENGTH_LONG).show();}}@OverridepublicvoidonFailure(Throwableerror,StringerrorMessage){// http or parsing errorif(errorMessage!=null){Toast.makeText(MainActivity.this,errorMessage,Toast.LENGTH_LONG).show();}else{Toast.makeText(MainActivity.this,error.getMessage(),Toast.LENGTH_LONG).show();}}});}});}}
More comments to the serivce call code:
I’ve added comments in the code so the whole service call flow should be easy to understand.
We used the eBay Shopping findPopularItems call, which takes a keyword as input, and will return a list of matched popular items on eBay, for demo, we just need one item to display, so we set maxEntries to 1.
In the success handling logic, we show the title of the returned item..
eBay Shopping service supports response resident error(RRE), so even we get a success response, we still need to check the response for resident error and handle it accordingly.
Final Step - Run the Demo
Let’s run the demo on simulator, see a screen shot below:
let’s also try a soap fault case, for example, if you forget to fill in your eBayAppId in the shared client, then you will get:
This is just a bare minimum eBay Shopping service based application, for a demo with more functions, please see the eBayDemoApp sample in the sample\webservice folder of Nano source, eBayDemoApp is a composite app which calls two eBay services behind, this app searches eBay by calling eBay Finding service, shows a list of matched items on UI, when an item is clicked, it will show item details by calling eBay Shopping service, see a screen shot below.
Now it’s your turn to create Android applications based on eBay Shopping and eBay Finding web services, see your next great service based app.