API рекламы продуктов Amazon через Java / SOAP - PullRequest
8 голосов
/ 01 декабря 2011

Я играл с 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#Java

На 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");

    }
}

Вот что я получаю ... Я былв надежде увидеть, что некоторые книги по Звездным войнам, доступные на Amazon, будут выгружены на мою консоль: - /:

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

Что я делаю не так (обратите внимание, что во втором цикле for не выводится ни один «элемент»,потому что его пусто)?Как я могу устранить это или получить соответствующую информацию об ошибке?

Ответы [ 4 ]

10 голосов
/ 04 декабря 2011

Я не использую SOAP API, но ваши требования к Баунти не указывали, что он должен использовать SOAP только для того, чтобы вы вызывали Amazon и получали результаты. Итак, я опубликую этот рабочий пример с использованием REST API, который по крайней мере будет соответствовать вашим заявленным требованиям:

Я хотел бы получить пример рабочего кода, который попадает на сервер amazon и возвращает результаты

Для выполнения требований подписи вам потребуется загрузить следующее:

http://associates -amazon.s3.amazonaws.com / Подписанные-запросы / образцы / amazon-product-advt-api-sample-java-query.zip

Разархивируйте его, возьмите файл 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.

4 голосов
/ 05 декабря 2011

Это сработало (мне пришлось добавить мой 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");

    }
}
1 голос
/ 01 декабря 2011

Вам необходимо вызвать методы 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());
}
1 голос
/ 01 декабря 2011

Похоже, что объект ответа не переопределяет toString (), поэтому, если он содержит какой-либо ответ об ошибке, простая его печать не скажет вам, что такое ответ об ошибке. Вам нужно посмотреть на API, какие поля возвращаются в объекте ответа, и распечатать их по отдельности. Либо вы получите очевидное сообщение об ошибке, либо вам придется вернуться к их документации, чтобы попытаться выяснить, что не так.

...