【问题标题】:Amazon Product Advertising API signed request with Java使用 Java 签名的亚马逊产品广告 API 请求
【发布时间】:2011-03-12 12:35:01
【问题描述】:

经过数小时的修补和多次阅读整个互联网后,我只是不知道如何签署使用产品广告 API 的请求。

到目前为止,我设法从提供的 WSDL 文件生成了一个客户端。我为此使用了亚马逊的教程。你可以在这里找到它:

Tutorial for generating the web service client

到目前为止没有问题。为了测试客户端,我编写了一小段代码。该代码旨在简单地获取有关产品的一些信息。产品由其 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");
  }
}

如您所见,我没有在请求上签名的部分。我已经研究了很多使用的类,但没有找到签署请求的方法。

那么,如何签署请求?

我实际上在文档中找到了一些东西:request authentication

但他们不使用自己的 API。建议的解决方案或多或少仅用于手动使用。因此,我查看了客户端类,以确定是否可以获取请求 URL,并将请求登录所需的所有部分放入我自己。但是没有这样的方法。

我希望有人能指出我做错了什么。


这就是我为解决问题所做的。所有功劳归于Jon 和亚马逊论坛的人。

在我概述我所做的之前,这里有一个链接到帮助我解决问题的帖子:Forum Post on Amazon forums

我下载了帖子中链接的 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");
  }
}

最后的 println 或多或少没用。但它有效。我还使用链接的 WSDL Jon 来生成一个新的 web 服务客户端。我刚刚更改了我在问题中发布的教程中的 URL。

【问题讨论】:

  • 感谢您发布此摘要,为我节省了一天的精力!
  • 另一件事:client-side API generation notes 并没有明确指出开发人员必须将 jaxws-custom.xml 文件输入到 wsimport 或 Jens 的示例'不使用它生成的代码进行编译。

标签: java web-services api amazon-web-services amazon


【解决方案1】:

创建服务后试试这个

service.setHandlerResolver(new AwsHandlerResolver(my_AWS_SECRET_KEY));

由于 AwsHandlerResolver 使用 Base64 编码,您需要将 this 类和 this jar 文件添加为对项目的引用。

您需要将 AwsHandlerResolver 文件重命名为类的名称,因为文件名都是小写的。

我认为您拥有的其余代码都很好。

WSDL 是http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl

【讨论】:

  • WSDL 是从 2010 年 4 月开始的。所以它相当新。你使用谷歌的示例代码吗?我曾经在那里发现了一些看起来非常像你所拥有的东西。由亚马逊提供的 WSDL 生成的客户端不包含 AwsHandlerResolver 之类的类。不过还是谢谢你的建议!
  • 你的回答很棒。亚马逊论坛上的链接帖子对我帮助很大!我编辑了我的帖子以包含您的答案。非常感谢乔恩。
  • 您使用的是 Windows 吗?我刚试了一下,得到了空响应,但 Mac 上的相同代码得到了结果。
【解决方案2】:

这个讨论和相关的亚马逊帖子帮助我让客户工作。话虽如此,我觉得解决方案可以在以下方面进行改进:

  1. 不鼓励在代码中设置 WebService 处理程序。推荐使用 XML 配置文件和对应的 @HandlerChain 注解。
  2. 在这种情况下不需要 SOAPHandler,LogicalHandler 就可以了。 SOAPHandler 比 LogicalHandler 具有更大的范围,并且在涉及代码时,更多的访问权限并不总是好的。
  3. 填充签名生成、添加节点并在一个处理程序中打印请求似乎有点太多了。可以将这些分离出来以分离责任和易于测试。一种方法是使用 XSLT 转换添加节点,以便处理程序可以忽略转换逻辑。然后可以链接另一个处理程序,它只打印请求。 Example

【讨论】:

    【解决方案3】:

    我在春天做了这个,效果很好。

    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());
        }
    }
    }
    

    【讨论】:

    • 最好能说明代码的作用,而不是仅仅粘贴代码
    【解决方案4】:

    您也可以使用 IntentBrite API 实现相同的获利结果

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-12
      • 1970-01-01
      • 2012-08-25
      • 1970-01-01
      • 2012-05-15
      相关资源
      最近更新 更多