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

发布于 2024-09-08 13:28:57 字数 3270 浏览 2 评论 0原文

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

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

生成 Web 服务客户端的教程< /a>

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

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

我下载了帖子中链接的 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。

After many hours of tinkering and reading the whole internet several times I just can't figure out how to sign requests for use with the Product Advertising API.

So far I managed to generate a client from the provided WSDL file. I used a tutorial by Amazon for this. You can find it here:

Tutorial for generating the web service client

So far no problems. To test the client I wrote a small piece of code. The code is intended to simply get some information about a product. The product is specified by its ASIN.

The code:

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

As you can see there is no part where I sign the request. I have worked my way through a lot of the classes used and found no methods for signing the request.

So, how to sign a request?

I actually found something in the documentation: request authentication

But they don't use their own API. The proposed solutions are more or less for manual use only. So I looked in the client classes to sort out if I could get the request URL and put all the parts needed for request signing in myself. But there are no such methods.

I hope someone can point out what I am doing wrong.


This is what I did to solve the problem. All the credit goes to Jon and the guys of the Amazon forums.

Before I outline what I did, here is a link to the post which helped me to solve the problem: Forum Post on Amazon forums.

I downloaded the awshandlerresolver.java which is linked in the post. Than I modified my own code so it looks like this:

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

The println on the end are more or less useless. But it works. I also used the WSDL Jon linked to generate a new webservice client. I just changed the URLs in the tutorial I posted in my question.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

陌若浮生 2024-09-15 13:28:57

创建服务后尝试此操作

service.setHandlerResolver(new AwsHandlerResolver(my_AWS_SECRET_KEY));

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

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

我认为你的其余代码都很好。

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

Try this afer you create the service

service.setHandlerResolver(new AwsHandlerResolver(my_AWS_SECRET_KEY));

You'll need this class and this jar file to add as a reference to your project as AwsHandlerResolver uses Base64 encoding.

You'll need to rename the AwsHandlerResolver file to the name of the class as the file name is all lower case.

I think the rest of the code you have is fine.

The WSDL is http://webservices.amazon.com/AWSECommerceService/AWSECommerceService.wsdl

寄居人 2024-09-15 13:28:57

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

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

This discussion and the related Amazon post helped me get the client working. That being said, I felt that the solution could be improved with regards to the following:

  1. Setting WebService handlers in code is discouraged. A XML configuration file and a corresponding @HandlerChain annotation are recommended.
  2. A SOAPHandler is not required in this case, LogicalHandler would do just fine. A SOAPHandler has more reach than a LogicalHandler and when it comes to code, more access is not always good.
  3. Stuffing the signature generation, addition of a Node and printing the request in one handler seems like a little too much. These could be separated out for separation of responsibility and ease of testing. One approach would be to add the Node using a XSLT transformation so that the handler could remain oblivious of the transformation logic. Another handler could then be chained which just prints the request.
    Example
以可爱出名 2024-09-15 13:28:57

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

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

i did this in spring it's working fine.

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());
    }
}
}
终止放荡 2024-09-15 13:28:57

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

You could achieve the same monetization outcomes with the IntentBrite API as well

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文