API рекламы продуктов Amazon подписал запрос с Java
После многих часов работы над Интернетом несколько раз я просто не могу понять, как подписывать запросы на использование API рекламы продукта.
До сих пор мне удалось сгенерировать клиента из предоставленного файла WSDL. Я использовал учебник Amazon для этого. Вы можете найти это здесь:
Учебник по генерации клиента веб-сервиса
Пока проблем нет. Для проверки клиента я написал небольшой фрагмент кода. Код предназначен просто для получения некоторой информации о продукте. Продукт указан по ASIN.
Код:
package client;
import com.ECS.client.jax.AWSECommerceService;
import com.ECS.client.jax.AWSECommerceServicePortType;
import com.ECS.client.jax.ItemLookup;
import com.ECS.client.jax.ItemLookupResponse;
import com.ECS.client.jax.ItemLookupRequest;
public class Client {
public static void main(String[] args) {
System.out.println("API Test startet");
AWSECommerceService service = new AWSECommerceService();
AWSECommerceServicePortType port = service.getAWSECommerceServicePort();
ItemLookupRequest itemLookup = new ItemLookupRequest();
itemLookup.setIdType("ASIN");
itemLookup.getItemId().add("B000RE216U");
ItemLookup lookup = new ItemLookup();
lookup.setAWSAccessKeyId("<mykeyishere>");
lookup.getRequest().add(itemLookup);
ItemLookupResponse response = port.itemLookup(lookup);
String r = response.toString();
System.out.println("response: " + r);
System.out.println("API Test stopped");
}
}
Как видите, там нет части, где я подписываю запрос. Я прошел через многие используемые классы и не нашел методов для подписания запроса.
Итак, как подписать запрос?
Я на самом деле что-то нашел в документации: запрос аутентификации
Но они не используют свой собственный API. Предлагаемые решения более или менее предназначены только для ручного использования. Поэтому я посмотрел в клиентских классах, чтобы разобраться, смогу ли я получить URL запроса и поместить все части, необходимые для подписания запроса, в себя. Но таких методов нет.
Я надеюсь, что кто-то может указать, что я делаю неправильно.
Это то, что я сделал, чтобы решить проблему. Вся заслуга Jon и ребят из форумов Amazon.
Прежде чем я обрисую в общих чертах то, что я сделал, вот ссылка на пост, который помог мне решить проблему: пост на форуме Amazon.
Я скачал файл awshandlerresolver.java, ссылка на который есть в посте. Затем я изменил свой собственный код, чтобы он выглядел так:
package client;
import com.ECS.client.jax.AWSECommerceService;
import com.ECS.client.jax.AWSECommerceServicePortType;
import com.ECS.client.jax.ItemLookup;
import com.ECS.client.jax.ItemLookupResponse;
import com.ECS.client.jax.ItemLookupRequest;
public class Client {
public static void main(String[] args) {
System.out.println("API Test startet");
AWSECommerceService service = new AWSECommerceService();
service.setHandlerResolver(new AwsHandlerResolver("<Secret Key>")); // important
AWSECommerceServicePortType port = service.getAWSECommerceServicePort();
ItemLookupRequest itemLookup = new ItemLookupRequest();
itemLookup.setIdType("ASIN");
itemLookup.getItemId().add("B000RE216U");
ItemLookup lookup = new ItemLookup();
lookup.setAWSAccessKeyId("<Access Key>"); // important
lookup.getRequest().add(itemLookup);
ItemLookupResponse response = port.itemLookup(lookup);
String r = response.toString();
System.out.println("response: " + r);
System.out.println("API Test stopped");
}
}
Печать на конце более или менее бесполезна. Но это работает. Я также использовал связанный с WSDL Jon для создания нового клиента веб-сервиса. Я только что изменил URL в учебнике, который я разместил в своем вопросе.
4 ответа
Попробуйте это после создания сервиса
service.setHandlerResolver(new AwsHandlerResolver(my_AWS_SECRET_KEY));
Вам понадобится этот класс и этот jar-файл для добавления в качестве ссылки на ваш проект, так как AwsHandlerResolver использует кодировку Base64.
Вам нужно будет переименовать файл AwsHandlerResolver в имя класса, так как имя файла в нижнем регистре.
Я думаю, что остальная часть кода у вас в порядке.
WSDL является http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl
Это обсуждение и связанный пост Amazon помогли мне заставить клиента работать. При этом я чувствовал, что решение может быть улучшено в отношении следующего:
- Установка обработчиков WebService в коде не рекомендуется. Рекомендуются файл конфигурации XML и соответствующая аннотация @HandlerChain.
- В этом случае SOAPHandler не требуется, LogicalHandler вполне подойдет. SOAPHandler имеет больший охват, чем LogicalHandler, и когда дело доходит до кода, больший доступ не всегда хорош.
- Заполнение генерации подписи, добавление узла и печать запроса в одном обработчике кажется слишком сложным. Они могут быть разделены для разделения ответственности и удобства тестирования. Один из подходов заключается в добавлении узла с использованием XSLT-преобразования, чтобы обработчик мог не замечать логику преобразования. Затем может быть связан другой обработчик, который просто печатает запрос. пример
Я сделал это весной, все работает нормально.
package com.bookbub.application;
import com.ECS.client.jax.*;
import com.ECS.client.jax.ItemSearch;
import javax.xml.ws.Holder;
import java.math.BigInteger;
import java.util.List;
public class TestClient {
private static final String AWS_ACCESS_KEY_ID = "AI*****2Y7Z****DIHQ";
private static final String AWS_SECRET_KEY = "lIm*****dJuiy***YA+g/vnj/Ix*****Oeu";
private static final String ASSOCIATE_TAG = "****-**";
public static void main(String[] args) {
TestClient ist = new TestClient();
ist.runSearch();
}
public void runSearch()
{
AWSECommerceService service = new AWSECommerceService();
service.setHandlerResolver(new AwsHandlerResolver(AWS_SECRET_KEY));
AWSECommerceServicePortType port = service.getAWSECommerceServicePort();
ItemSearchRequest request = new ItemSearchRequest();
request.setSearchIndex("Books");
request.setKeywords("java web services up and running oreilly");
ItemSearch search = new ItemSearch();
search.getRequest().add(request);
search.setAWSAccessKeyId(AWS_ACCESS_KEY_ID);
Holder<OperationRequest> operation_request =null;
Holder<List<Items>> items = new Holder<List<Items>>();
port.itemSearch(
search.getMarketplaceDomain(),
search.getAWSAccessKeyId(),
search.getAssociateTag(),
search.getXMLEscaping(),
search.getValidate(),
search.getShared(),
search.getRequest(),
operation_request,
items);
java.util.List<Items> result = items.value;
BigInteger totalPages = result.get(0).getTotalResults();
System.out.println(totalPages);
for (int i = 0; i < result.get(0).getItem().size(); ++i)
{ Item myItem = result.get(0).getItem().get(i);
System.out.print(myItem.getASIN());
System.out.print(", ");
System.out.println(myItem.getDetailPageURL());
System.out.print(", ");
System.out.println(myItem.getSmallImage() == null ? "" : myItem.getSmallImage().getURL());
}
}
}
Вы также можете достичь тех же результатов монетизации с помощью API IntentBrite