API рекламы продуктов Amazon через Java/SOAP
Я играл с API рекламы продуктов Amazon и не могу получить запрос, чтобы пройти и предоставить мне данные. Я работал над этим: http://docs.amazonwebservices.com/AWSECommerceService/2011-08-01/GSG/ и это: API рекламы продуктов Amazon подписал запрос с Java
Вот мой код... Я сгенерировал привязки SOAP, используя это: http://docs.amazonwebservices.com/AWSECommerceService/2011-08-01/GSG/YourDevelopmentEnvironment.html
На Classpath у меня есть только: 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");
}
}
Вот что я получаю... Я надеялся увидеть, что некоторые книги о Звездных войнах, доступные на Амазоне, будут выгружены на мою консоль: - /:
API Test started
response: com.ECS.client.jax.ItemSearchResponse@7a6769ea
com.ECS.client.jax.Items@1b5ac06e
API Test stopped
Что я делаю не так (обратите внимание, что ни один "элемент" во втором цикле for не выводится, потому что он пуст)? Как я могу устранить это или получить соответствующую информацию об ошибке?
4 ответа
Это сработало (мне пришлось добавить свой AssociateTag в запрос):
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");
}
}
Я не использую SOAP API, но в ваших требованиях к Баунти не указано, что он должен использовать SOAP только для того, чтобы вы хотели позвонить в Amazon и получить результаты. Итак, я опубликую этот рабочий пример с использованием REST API, который по крайней мере будет соответствовать вашим заявленным требованиям:
Я хотел бы некоторый рабочий пример кода, который попадает на сервер Amazon и возвращает результаты
Вам нужно скачать следующее, чтобы выполнить требования подписи:
Распакуйте его и возьмите com.amazon.advertising.api.sample.SignedRequestsHelper.java
файл и положить его прямо в ваш проект. Этот код используется для подписи запроса.
Вам также необходимо скачать Apache Commons Codec 1.3 из следующего и добавить его в ваш путь к классу, т.е. добавить в библиотеку вашего проекта. Обратите внимание, что это единственная версия кодека, которая будет работать с вышеуказанным классом (SignedRequestsHelper
)
http://archive.apache.org/dist/commons/codec/binaries/commons-codec-1.3.zip
Теперь вы можете скопировать и вставить следующее, убедившись, что заменить your.pkg.here
с правильным названием пакета и замените SECRET
и KEY
свойства:
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);
}
}
Как вы можете видеть, это гораздо проще в настройке и использовании, чем SOAP API. Если у вас нет особых требований для использования SOAP API, я настоятельно рекомендую вам использовать вместо этого REST API.
Одним из недостатков использования REST API является то, что результаты не разбиты на объекты для вас. Это можно исправить, создав необходимые классы на основе wsdl.
Вам нужно вызвать методы get для объекта Item, чтобы получить его детали, например:
for (Item item : itemList.getItem()) {
System.out.println(item.getItemAttributes().getTitle()); //Title of item
System.out.println(item.getDetailPageURL()); // Amazon URL
//etc
}
Если есть какие-либо ошибки, вы можете получить их, вызвав getErrors()
if (response.getOperationRequest().getErrors() != null) {
System.out.println(response.getOperationRequest().getErrors().getError().get(0).getMessage());
}
Похоже, что объект ответа не переопределяет toString(), поэтому, если он содержит какой-либо ответ об ошибке, простая его печать не скажет вам, что такое ответ об ошибке. Вам нужно будет посмотреть на API, какие поля возвращаются в объекте ответа, и распечатать их по отдельности. Либо вы получите очевидное сообщение об ошибке, либо вам придется вернуться к их документации, чтобы попытаться выяснить, что не так.