This article demonstrates how to build an ADF application on top of the Amazon WebServices for searching books.
1. Start jdeveloper 10.1.3. 2.0(or newer)
2. Build a new Application
Application name: AmazonWebservice
Directory name: c:\projects\AmazonWebservice
Application Package prefix: aws
Application Template: Web Application[JSF, ADF BC]
3. Rightmousebutton at viewController > click new. New Gallery window opens.
Select Business Tier > Web Services > Web Service Proxy.
4. You will see the Create Web Service Proxy window. Enter at the WSDL Document URL:
http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl
and click next.
– The proxy model has been made.
– At step 2 click finish.
– The webservice proxy is ready to use.
– The projectstructure should look like this:
5. We are going to make a new java class file. This file represents the book object, which we need for the library.
– Rightmousebutton at viewController > click new. New Gallery window opens.
– Select general > Java Class
– Name: book
– Package: aws.item
– Extends: java.lang.Object
– Public: checked
– Generate Default Constructor: checked
– Generate Main Method: unchecked
6. We are now implementing the getters and setters for the book.java class.
Enter the following in book.java class:
private String title;
private String url;
private String isbn;
private String publisher;
private String author;
Look at the picture below.
– select in the main menu of jdeveloper > source > Generate Accessors
– select all items and click ok.
– the getters and setter will be generated.
7. Define the book constructor in book.java class, like the example below.
public book(String title, String url, String isbn , String publisher, String author) {
this.title = title;
this.url = url;
this.isbn = isbn;
this.publisher = publisher;
this.author = author;
}
8. Book.java file is ready
9. The next step for building an Amazon Webservice implementation with ADF in jdeveloper, is building a front-end to show the results from our search actions. For our front-end we will build a jsp file.
– Rightmousebutton at viewController > click new
Step 1
– Select in New gallery window Web Tier > JSF > JSF JSP
– File Name: AmazonSearch.jsp
– Directory Name: c:\projects\AmazonWebservice\ViewController\public_html
– Type: JSP_Page
– Mobile: unckeched
Step 2
– Select: Do Not Automatically Expose UI Components in a Managed Bean
Step 3
– select the libraries:
– ADF Faces Components 10_1_3_2_0
– ADF Faces HTML 10_1_3_2_0
– JSF Core 1.0
– JSF HTML 1.0
Click finish.
10. Open faces-config.xml file.
– Select the overview tab
– Select managed beans and click new.
– Enter the next settings in your create managed bean window:
– Name: AmazonWebSearch
– Class: aws.backing.AmazonSearch
– Scope: session
– Generate Class I fit Does Not Exist: checked
– An AmazonSearch.java class file is generated in the aws.backing package:
11. Return to AmazonSearch.jsp file
Open the structure window for the AmazonSearch.jsp file(the file is in design mode).
– Select tab “design†in the structure window
– Drag from the Component Palette > ADF Faces Core > PanelPage element to h:form in the structure window.
– Drag from the Component palette > ADF Faces Core > Table element to af:PanelPage
– An Insert Table window opens in your screen.
Step 1
– Select Bind now
– value: #{AmazonWebSearch.books}
– var: book
Step 2
– header: Title. Value: #{book.title}. Component: af:outputText
– header: Isbn. Value: #{book.isbn}. Component: af:outputText
– header: Book_image. Value: #{book.url}. Component: af:objectImage
Step 3
– Select Title > is sortable: checked > sort property: #{book.title}
– Select Isbn > is sortable: checked > sort property: #{book.isbn}
Step 4
– Include Table Banding: checked > select rows > Banding interval: 1
– Click finish.
– Enter in the table properties > rows: 10
– Drag from the Component Palette > ADF Faces Core > MenuBar element to the menu2 facet in the panelpage
– Drag from the Component Palette > JSF HTML > Panel grid element to the af:menuBar element. Define the number of columns for the panelGrid is 4.
– Drag from the Component Palette > ADF Faces Core > OutputText element to the panelgrid.
– Enter Selection at the value property, define color > white
– Drag from the Component Palette > ADF Faces Core > SelectOneChoice element to the panelgrid.
– Insert SelectOneChoice window opens.
– Select create list
– Item Label: Title. Item Value: title
– Item Label: Author. Item Value: author
– Item Label: Isbn. Item Value: isbn
– Item Label: Keyword. Item Value: keyword
– Make sure that the label property is empty, then click ok.
– Drag from the Component Palette > ADF Faces Core > inputText element to the panelgrid. Make sure that the label property is empty.
– Drag the Component Palette > ADF Faces Core > CommandButton element to the panelgrid. Enter Search at the text property of the commandButton object.
– Select selectOneChoice element and enter: searchCriteria at the id property.
– Select inputText element and enter: searchValue at the id property.
– Select commandButten element and enter: searchButton at the id property.
The structure of the components should look like this.
12. The next step that we are going to make is realising a connection with the AmazonSearch.java class with the components selectOneChoice, inputText and commandButton.
– Select selectOneChoice > binding(Propery Inspector) > click .
– Binding window opens.
– Managed Bean: AmazonWebSearch
– Property > new.
– Create Property window opens
– Type searchCriteria > ok > ok
– Select inputText > binding(Propery Inspector) > click .
– Binding window opens.
– Managed Bean: AmazonWebSearch
– Property > new.
– Create Property window opens
– Type searchValue > ok > ok
– Select AmazonSearch.java and insert:
ArrayList books = new ArrayList();
See example:
– ArrayList will be red underlined, import java.util.ArrayList package.
– We need the get and set method for the books ArrayList. Select in the main menu source > Generate Accessors, then select books item and click ok.
Copy and paste the search() method in the search.java class.
public String search() throws Exception
{
String criteria = (String) searchCriteria.getValue();
String value = (String) searchValue.getValue();
books = searchBooks(criteria, value);
this.setBooks(books);
return null;
}
Open the AmazonSearch.jsp file
– Select commandButton > action(Property Inspector)
– Enter the value: #{AmazonWebSearch.search}
The EL expression uses the method search() in the AmazonSearch.java class.
13. We must now implement the methods for obtaining results of the search action we will do in our AmazonSearch.jsp page. We’ve already made a method which is used by the commandButton.
14. The method search() triggers the method searchBooks(). This method has two parameters. The first parameter is the selected criteria in the jsp file and the second parameter is the entered value by the user.
– The for loop within the method is used to call different pages. Amazon has restricted the maximum page at 400.
– An if statement is used to determine which method must be called to get the proper data.
– The rest of the method is used to put the book items in an ArrayList.
Copy and paste the method displayed below in the AmazonSearch.java file:
public ArrayList searchBooks(String criteria, String value) throws Exception
{
ArrayList books = new ArrayList();
ItemsType2 [] itemsArray;
int pageNo = 1;
for(int counter = 1; counter < pageNo + 1; counter++)
{
if(!criteria.equals(“isbn”))
itemsArray = OtherSearch(criteria, value, counter);
else
itemsArray = ISBNSearch(value);
if ( itemsArray == null )
throw new Exception ( “Server Error – empty response!” );
if ( itemsArray[0].getRequest().getErrors() != null )
throw new Exception ( itemsArray [0].getRequest().getErrors().getError()[0].getMessage() );
try
{
if ( itemsArray != null )
{
for ( ItemsType2 items : itemsArray )
{
if ( items != null )
{
if(!criteria.equals(“isbn”))
{
pageNo = Integer.parseInt(items.getTotalPages().toString());
if(pageNo >= 400)
pageNo = 399;
}
/**********************************************************
* Items::Item
/**********************************************************/
ItemType2 [] itemArray = items.getItem();
if ( itemArray != null )
{
for ( ItemType2 item : itemArray )
{
if ( item != null )
{
/**********************************************************
* Item::ItemAttributes
/**********************************************************/
Image smallImage = item.getSmallImage();
ItemAttributes itemAttributes = item.getItemAttributes();
String authorString = “”;
if ( itemAttributes != null )
{
for ( String auth : itemAttributes.getAuthor() )
&n
bsp; authorString += auth + “, “;
String url;
try
{
url = smallImage.getURL();
}
catch( Exception ex )
{
url = “/images/k4transparant.gif”;
}
books.add( new book(itemAttributes.getTitle()
, url
, itemAttributes.getISBN()
, itemAttributes.getPublisher()
, authorString.substring(0,(authorString.length()-2))
));
}
}
}
}
}
}
}
}
catch ( Exception ex )
{
System.out.println( ex.toString());
}
}
return books;
}
15. The ItemSearchRequest object is been used to search with the criteria’s: author, title, keyword. Therefore there has been made a different method which returns a ItemsType2[] array. The returnvalue will be used to retrieve the items for the searchBooks method. The method is displayed below. Copy and paste this method into AmazonSearch.java class.
private ItemsType2[] OtherSearch(String searchCriteria, String searchValue, int pageNo) throws Exception
{
aws.view.proxy.AWSECommerceServicePortClient myPort = new aws.view.proxy.AWSECommerceServicePortClient();
ItemSearch itemSearch = new ItemSearch();
ItemSearchRequest request = new ItemSearchRequest();
//AWS subscription ID from Amazon so you can use their Web services
itemSearch.setSubscriptionId (“08YCQ8XR0HCKRJZFBK82”);
request.setResponseGroup (new String [] {“Images”,”ItemAttributes”,”ItemIds”});
if(searchCriteria.equals(“author”))
request.setAuthor(searchValue);
if(searchCriteria.equals(“title”))
request.setTitle(searchValue);
if(searchCriteria.equals(“keyword”))
request.setKeywords(searchValue);
request.setItemPage(new BigInteger(“”+pageNo));
request.setSearchIndex (“Books”);
itemSearch.setRequest ( new ItemSearchRequest [] { request } );
// Get the response
MultiOperationResponse response = myPort.multiOperation(null,itemSearch,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null);
if ( response == null )
throw new Exception (“Server Error – no response recieved!”);
ItemsType2 [] itemsArray = response.getItemSearchResponse().getItems();
return itemsArray;
}
16. To enable the searchcriteria: isbn, we cannot use the ItemSearchRequest object, but we must use the ItemLookupRequest object. Therefore we have to make an extra method to retrieve the items in an ItemsType2[] array. The method is displayed below. Copy and paste the method to the AmazonSearch.java class file.
private ItemsType2[] ISBNSearch(String isbn) throws Exception
{
aws.view.proxy.AWSECommerceServicePortClient myPort = new aws.view.proxy.AWSECommerceServicePortClient();
ItemLookup itemLookup = new ItemLookup();
ItemLookupRequest request = new ItemLookupRequest();
//AWS subscription ID from Amazon so you can use their Web services
itemLookup.setSubscriptionId ( “0525E2PQ81DD7ZTWTK82” );
request.setMerchantId(“All”);
request.setCondition(Condition.New);
request.setItemId(new String[]{isbn});
request.setResponseGroup (new String [] {“Images”,”ItemAttributes”,”ItemIds”});
itemLookup.setRequest ( new ItemLookupRequest [] { request } );
// Get the response
MultiOperationResponse response = myPort.multiOperation(null,null,itemLookup,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null,null);
if ( response == null )
throw new Exception ( “Server Error – no response recieved!” );
ItemsType2 [] itemsArray = response.getItemLookupResponse().getItems();
return itemsArray;
}
If the myPort.multiOperation, doesn’t work! You have to search in AWSECommerceServicePortClient.java file the correct method to use for returning a correct response object.
17. The next import statements must be realised in AmazonSearch.java(Suggestion! Copy and paste)
import aws.item.book;
import aws.view.proxy.Condition;
import aws.view.proxy.Image;
import aws.view.proxy.ItemAttributes;
import aws.view.proxy.ItemLookup;
import aws.view.proxy.ItemLookupRequest;
import aws.view.proxy.ItemSearch;
import aws.view.proxy.ItemSearchRequest;
import aws.view.proxy.ItemType2;
import aws.view.proxy.ItemsType2;
import aws.view.proxy.MultiOperationResponse;
import java.math.BigInteger;
import java.util.ArrayList;
import oracle.adf.view.faces.component.core.input.CoreInputText;
import oracle.adf.view.faces.component.core.input.CoreSelectOneChoice;
18. The final thing we have to do is creating a map in de project and insert a transparent gif file in this map.
– Create a map in the window explorer like the example below, call the map: images
– Find a transparant picture at google pictures
– Call it k4transparant.gif
– Resize the picture if you are compelled to.
– An example of a transparent picture is shown next.
19. Finished, you are now able to run the AmazonSearch.jsp file, an example of the project is shown below.
20. Look at the http://www.awszone.com/ for any useful documentation.
21. Developer guide: http://developer.amazonwebservices.com/connect/kbcategory.jspa?categoryID=19
Thank you for your reply and mentioning the amazon package for apex.
Anticipating the AMIS Query of upcoming Monday, perhaps nice to mention that for ApEx a packaged application is downloadable at http://www.oracle.com/technology/products/database/application_express/packaged_apps/packaged_apps.html#AMAZON, (also a whitepaper is available) offering the same functionaliaty based on Amazon. Thanks for this walkthrough how to implement it in ADF, maybe for comparison perhaps?