Amazon Product Advertising API through Java / SOAP

I play with the Amazon Product Advertising API and I cannot receive a request to go through and provide me with the data. I worked on this: http://docs.amazonwebservices.com/AWSECommerceService/2011-08-01/GSG/ and this: a signed Amazon Advertising API request with Java

Here is my code .. I created SOAP bindings using this: http://docs.amazonwebservices.com/AWSECommerceService/2011-08-01/GSG/YourDevelopmentEnvironment.html#Java

In Classpath, I only have: commons-codec.1.5.jar

import com.ECS.client.jax.AWSECommerceService; import com.ECS.client.jax.AWSECommerceServicePortType; import com.ECS.client.jax.Item; import com.ECS.client.jax.ItemLookup; import com.ECS.client.jax.ItemLookupRequest; import com.ECS.client.jax.ItemLookupResponse; import com.ECS.client.jax.ItemSearchResponse; import com.ECS.client.jax.Items; public class Client { public static void main(String[] args) { String secretKey = <my-secret-key>; String awsKey = <my-aws-key>; System.out.println("API Test started"); AWSECommerceService service = new AWSECommerceService(); service.setHandlerResolver(new AwsHandlerResolver( secretKey)); // important AWSECommerceServicePortType port = service.getAWSECommerceServicePort(); // Get the operation object: com.ECS.client.jax.ItemSearchRequest itemRequest = new com.ECS.client.jax.ItemSearchRequest(); // Fill in the request object: itemRequest.setSearchIndex("Books"); itemRequest.setKeywords("Star Wars"); // itemRequest.setVersion("2011-08-01"); com.ECS.client.jax.ItemSearch ItemElement = new com.ECS.client.jax.ItemSearch(); ItemElement.setAWSAccessKeyId(awsKey); ItemElement.getRequest().add(itemRequest); // Call the Web service operation and store the response // in the response object: com.ECS.client.jax.ItemSearchResponse response = port .itemSearch(ItemElement); String r = response.toString(); System.out.println("response: " + r); for (Items itemList : response.getItems()) { System.out.println(itemList); for (Item item : itemList.getItem()) { System.out.println(item); } } System.out.println("API Test stopped"); } } 

This is what I will return. I was hoping to see Amadon's Star Wars books coming out on my console: - /:

 API Test started response: com.ECS.client.jax.ItemSearchResponse@7a6769ea com.ECS.client.jax.Items@1b5ac06e API Test stopped 

What am I doing wrong (note that the "element" in the second loop of the loop does not print because it is empty)? How can I fix this problem or get relevant error information?

+8
java soap amazon jax-ws amazon-product-api
source share
4 answers

This ended up working (I had to add my request to the request):

 public class Client { public static void main(String[] args) { String secretKey = "<MY_SECRET_KEY>"; String awsKey = "<MY AWS KEY>"; System.out.println("API Test started"); AWSECommerceService service = new AWSECommerceService(); service.setHandlerResolver(new AwsHandlerResolver(secretKey)); // important AWSECommerceServicePortType port = service.getAWSECommerceServicePort(); // Get the operation object: com.ECS.client.jax.ItemSearchRequest itemRequest = new com.ECS.client.jax.ItemSearchRequest(); // Fill in the request object: itemRequest.setSearchIndex("Books"); itemRequest.setKeywords("Star Wars"); itemRequest.getResponseGroup().add("Large"); // itemRequest.getResponseGroup().add("Images"); // itemRequest.setVersion("2011-08-01"); com.ECS.client.jax.ItemSearch ItemElement = new com.ECS.client.jax.ItemSearch(); ItemElement.setAWSAccessKeyId(awsKey); ItemElement.setAssociateTag("th0426-20"); ItemElement.getRequest().add(itemRequest); // Call the Web service operation and store the response // in the response object: com.ECS.client.jax.ItemSearchResponse response = port .itemSearch(ItemElement); String r = response.toString(); System.out.println("response: " + r); for (Items itemList : response.getItems()) { System.out.println(itemList); for (Item itemObj : itemList.getItem()) { System.out.println(itemObj.getItemAttributes().getTitle()); // Title System.out.println(itemObj.getDetailPageURL()); // Amazon URL } } System.out.println("API Test stopped"); } } 
+4
source share

I do not use the SOAP API, but your Bounty requirements did not state that he should use SOAP only for what you wanted to call Amazon and get the results. So, I will publish this working example using the REST API, which will at least fulfill your stated requirements:

I need a working code code that gets to the amazon server and returns the results

To fulfill the signature requirements you need to download the following:

http://associates-amazon.s3.amazonaws.com/signed-requests/samples/amazon-product-advt-api-sample-java-query.zip

Unzip it and take the com.amazon.advertising.api.sample.SignedRequestsHelper.java file and put it directly into your project. This code is used to sign the request.

You will also need to download the Apache Commons Codec 1.3 from the following and add it to your class path, that is, add it to your project library. Please note that this is the only version of the codec that will work with the above class ( SignedRequestsHelper )

http://archive.apache.org/dist/commons/codec/binaries/commons-codec-1.3.zip

Now you can copy and paste the following to replace your.pkg.here with the correct package name and replace the SECRET and KEY properties:

 package your.pkg.here; import java.io.FileNotFoundException; import java.io.IOException; import java.io.StringWriter; import java.util.HashMap; import java.util.Map; import java.util.Properties; import java.util.logging.Level; import java.util.logging.Logger; import javax.xml.parsers.DocumentBuilder; import javax.xml.parsers.DocumentBuilderFactory; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.OutputKeys; import javax.xml.transform.Transformer; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import org.w3c.dom.Document; import org.xml.sax.SAXException; public class Main { private static final String SECRET_KEY = "<YOUR_SECRET_KEY>"; private static final String AWS_KEY = "<YOUR_KEY>"; public static void main(String[] args) { SignedRequestsHelper helper = SignedRequestsHelper.getInstance("ecs.amazonaws.com", AWS_KEY, SECRET_KEY); Map<String, String> params = new HashMap<String, String>(); params.put("Service", "AWSECommerceService"); params.put("Version", "2009-03-31"); params.put("Operation", "ItemLookup"); params.put("ItemId", "1451648537"); params.put("ResponseGroup", "Large"); String url = helper.sign(params); try { Document response = getResponse(url); printResponse(response); } catch (Exception ex) { Logger.getLogger(Main.class.getName()).log(Level.SEVERE, null, ex); } } private static Document getResponse(String url) throws ParserConfigurationException, IOException, SAXException { DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); Document doc = builder.parse(url); return doc; } private static void printResponse(Document doc) throws TransformerException, FileNotFoundException { Transformer trans = TransformerFactory.newInstance().newTransformer(); Properties props = new Properties(); props.put(OutputKeys.INDENT, "yes"); trans.setOutputProperties(props); StreamResult res = new StreamResult(new StringWriter()); DOMSource src = new DOMSource(doc); trans.transform(src, res); String toString = res.getWriter().toString(); System.out.println(toString); } } 

As you can see, this is much easier to configure and use than in the SOAP API. Unless you have a specific requirement for using the SOAP API, I would highly recommend using the REST API instead.

One of the drawbacks of using the REST API is that the results are not decoupled into objects for you. This could be fixed by creating the necessary classes based on wsdl.

+10
source share

It seems that the response object does not override toString (), so if it contains some kind of error response, just printing it will not tell you what the error response is. You will need to look at the api which fields will be returned in the response object and individually print them. Either you get an obvious error message, or you have to go back to your documentation to try to figure out what is wrong.

+1
source share

You need to call get methods on the Item object to get its data, for example:

 for (Item item : itemList.getItem()) { System.out.println(item.getItemAttributes().getTitle()); //Title of item System.out.println(item.getDetailPageURL()); // Amazon URL //etc } 

If there are any errors, you can get them by calling getErrors ()

 if (response.getOperationRequest().getErrors() != null) { System.out.println(response.getOperationRequest().getErrors().getError().get(0).getMessage()); } 
+1
source share

All Articles