使用 Java 签署的亚马逊商品广告 API 请求

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

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

生成 Web 服务客户端的教程

到目前为止没有问题。为了测试客户端,我写了一小段代码。该代码旨在简单地获取有关产品的一些信息。商品由其 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,并将自己放入请求登录所需的所有部分。但是没有这样的方法。

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


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

在我概述我所做的事情之前,这里有一个帮助我解决问题的帖子的链接:亚马逊论坛上的论坛帖子

我下载了 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 链接来生成一个新的 Web 服务客户端。我刚刚更改了我在问题中发布的教程中的URL。


答案 1

尝试创建服务

service.setHandlerResolver(new AwsHandlerResolver(my_AWS_SECRET_KEY));

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

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

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

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


答案 2

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

  1. 不建议在代码中设置 Web 服务处理程序。建议使用 XML 配置文件和相应的@HandlerChain注释。
  2. 在这种情况下,不需要 SOAPHandler,LogicalHandler 会做得很好。SOAPHandler比LogicHandler具有更大的影响力,当涉及到代码时,更多的访问并不总是好的。
  3. 填充签名生成,添加节点并在一个处理程序中打印请求似乎有点太多了。这些可以分离出来,以便分离责任和易于测试。一种方法是使用 XSLT 转换添加节点,以便处理程序可以忽略转换逻辑。然后可以链接另一个处理程序,该处理程序仅打印请求。

推荐