如何向 Amazon MWS / GetMatchingProductForId 发布请求
我想从亚马逊获取我长期以来查询的产品的详细信息(价格、排序...)。但我只能使用以下 koc 生成以下答案。我遇到的问题如下;
1-我收到时间戳错误。
2- 我无法发布下面的消息。
您能帮我解决这两个问题吗?
注意:我使用的是 Anypoint Studio 7.11.1。我可以使用 https reqeuest 连接器在 java 中发布答案。
Java 代码:
包 com.amazonservices.mws.products;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import java.util.TimeZone;
import java.util.Date;
public class signature {
private static final String CHARACTER_ENCODING = "UTF-8";
final static String ALGORITHM = "HmacSHA256";
public static void main() throws Exception {
String secretKey = "***";
String serviceUrl = "https://mws.amazonservices.com/";
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
df.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = new Date();
String timestamp = df.format(date);
HashMap<String, String> parameters = new HashMap<String,String>();
parameters.put("AWSAccessKeyId", urlEncode("***"));
parameters.put("Action", urlEncode("GetMatchingProductForId"));
parameters.put("IdList.Id.1", urlEncode("9781933988665"));
parameters.put("IdType", urlEncode("EAN"));
parameters.put("SellerId", urlEncode("***"));
parameters.put("SignatureMethod", urlEncode(ALGORITHM));
parameters.put("SignatureVersion", urlEncode("2"));
parameters.put("Timestamp", urlEncode(timestamp));
parameters.put("Version", urlEncode("2011-10-01"));
String formattedParameters = calculateStringToSignV2(parameters,
serviceUrl);
String signature = sign(formattedParameters, secretKey);
// Add signature to the parameters and display final results
parameters.put("Signature", urlEncode(signature));
System.out.println(calculateStringToSignV2(parameters,
serviceUrl));
}
private static String calculateStringToSignV2(
Map<String, String> parameters, String serviceUrl)
throws SignatureException, URISyntaxException {
// Sort the parameters alphabetically by storing
// in TreeMap structure
Map<String, String> sorted = new TreeMap<String, String>();
sorted.putAll(parameters);
// Set endpoint value
URI endpoint = new URI(serviceUrl.toLowerCase());
// Create flattened (String) representation
StringBuilder data = new StringBuilder();
//data.append("POST\n");
data.append(endpoint.getHost());
data.append("\n/Products/2011-10-01");
data.append("\n");
Iterator<Entry<String, String>> pairs =
sorted.entrySet().iterator();
while (pairs.hasNext()) {
Map.Entry<String, String> pair = pairs.next();
if (pair.getValue() != null) {
data.append( pair.getKey() + "=" + pair.getValue());
}
else {
data.append( pair.getKey() + "=");
}
// Delimit parameters with ampersand (&)
if (pairs.hasNext()) {
data.append( "&");
}
}
return data.toString();
}
/*
* Sign the text with the given secret key and convert to base64
*/
private static String sign(String data, String secretKey)
throws NoSuchAlgorithmException, InvalidKeyException,
IllegalStateException, UnsupportedEncodingException {
Mac mac = Mac.getInstance(ALGORITHM);
mac.init(new SecretKeySpec(secretKey.getBytes(CHARACTER_ENCODING),
ALGORITHM));
byte[] signature = mac.doFinal(data.getBytes(CHARACTER_ENCODING));
String signatureBase64 = new String(Base64.encodeBase64(signature),
CHARACTER_ENCODING);
return new String(signatureBase64);
}
private static String urlEncode(String rawValue) {
String value = (rawValue == null) ? "" : rawValue;
String encoded = null;
try {
encoded = URLEncoder.encode(value, CHARACTER_ENCODING)
.replace("+", "%20")
.replace("*", "%2A")
.replace("%7E","~"); ;
} catch (UnsupportedEncodingException e) {
System.err.println("Unknown encoding: " + CHARACTER_ENCODING);
e.printStackTrace();
}
return encoded;
}
}
代码输出:
AWSAccessKeyId=&Action=GetMatchingProductForId&SellerId=&Signature=ehjKNnTB5vhrOW3J1yWSz2T7c%3D&SignatureM方法=HmacSHA256&SignatureVersion=2&SubscribedFromDate=2013-05-01T12%3A00%3A00Z&时间戳=2013-05-02T16%3A00%3A00Z&版本=2011-10-01
Mulesoft 版本:7.11.1
应用程序 XML 详细信息:
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core"
xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd">
<flow name="awsFlow" doc:id="eeb85ef5-48cb-4c41-94ba-0e97a0765021" >
<scheduler doc:name="Scheduler" doc:id="f21548f8-1a12-4efa-adf8-27988ac587c5" >
<scheduling-strategy >
<fixed-frequency />
</scheduling-strategy>
</scheduler>
<ee:transform doc:name="Timestamp" doc:id="457efcd6-1388-49fe-88a8-f3d781d17593" >
<ee:message >
</ee:message>
<ee:variables >
<ee:set-variable variableName="requestmws" ><![CDATA[%dw 2.0
output application/json
fun getFormattedDate()=(now() >> "UTC") as String {format: "YYYY-MM-dd"} ++ "T" ++ (now() >> "UTC") as String {format: "HH:mm:ss"} ++ "Z"
---
{
myDate:"mws.amazonservices.com/Products/2011-10-01?AWSAccessKeyId=AKIAI56GX43PIHX4C7XA&Action=GetMatchingProductForId&IdList.Id.1=9781933988665&IdType=EAN&MarketplaceId=ATVPDKIKX0DER&SellerId=A28MSXET37R4N7&SignatureMethod=HmacSHA256&SignatureVersion=2&Version=2011-10-01&Timestamp=" ++ getFormattedDate() replace (':') with ('%3A')
}]]></ee:set-variable>
</ee:variables>
</ee:transform>
<ee:transform doc:name="Transform Message" doc:id="5b556411-1a0a-4d31-b536-48245baf3e0e" >
<ee:message >
</ee:message>
<ee:variables >
<ee:set-variable variableName="signature" ><![CDATA[%dw 2.0
import dw::Crypto
output application/json
---
{ "HMACWith" : Crypto::HMACWith("c4AL2hA6TQQ+vhiAti7OHQI10g7Q9bvOzVHfHOEn" as Binary, vars.requestmws.myDate as Binary, "HmacSHA256") }]]></ee:set-variable>
</ee:variables>
</ee:transform>
<ee:transform doc:name="Transform Message" doc:id="ef709e54-4f12-4db8-9088-9ccb203fda07">
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output application/java
---
{
b : vars.requestmws.myDate ++ "&Signature=" ++ vars.signature.HMACWith
}]]></ee:set-payload>
</ee:message>
</ee:transform>
<http:request method="POST" doc:name="Request" doc:id="9301bca2-067f-48a1-badc-4dd6c03a288d" url='#["https://" ++ payload.b]'>
<http:headers ><![CDATA[#[output application/java
---
{
"User-Agent" : "Java/1.8.0_201",
"Content-Type" : "text/xml"
}]]]></http:headers>
</http:request>
<error-handler >
<on-error-continue enableNotifications="true" logException="true" doc:name="On Error Continue" doc:id="27be6630-7439-43c9-86b5-c53c6693f0c7" type="ANY">
<logger level="INFO" doc:name="Logger" doc:id="077e3a7c-902a-48bc-aa8d-6a18af941487" message="#[message]"/>
</on-error-continue>
</error-handler>
</flow>
</mule>
谢谢。
I want to get the details (Price, sorting ...) of the products that I have been querying for a long time from amazon. But I was only able to generate the following answer with the following koc. The problems I encountered are as follows;
1- I am getting timestamp error.
2- I was unable to POST the message below.
Can you help me with these two issues?
Note: I am using Anypoint Studio 7.11.1. I can post the answer in java with https reqeuest connector.
Java Code:
package com.amazonservices.mws.products;
import java.io.UnsupportedEncodingException;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URLEncoder;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.SignatureException;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import org.apache.commons.codec.binary.Base64;
import java.util.TimeZone;
import java.util.Date;
public class signature {
private static final String CHARACTER_ENCODING = "UTF-8";
final static String ALGORITHM = "HmacSHA256";
public static void main() throws Exception {
String secretKey = "***";
String serviceUrl = "https://mws.amazonservices.com/";
SimpleDateFormat df = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
df.setTimeZone(TimeZone.getTimeZone("UTC"));
Date date = new Date();
String timestamp = df.format(date);
HashMap<String, String> parameters = new HashMap<String,String>();
parameters.put("AWSAccessKeyId", urlEncode("***"));
parameters.put("Action", urlEncode("GetMatchingProductForId"));
parameters.put("IdList.Id.1", urlEncode("9781933988665"));
parameters.put("IdType", urlEncode("EAN"));
parameters.put("SellerId", urlEncode("***"));
parameters.put("SignatureMethod", urlEncode(ALGORITHM));
parameters.put("SignatureVersion", urlEncode("2"));
parameters.put("Timestamp", urlEncode(timestamp));
parameters.put("Version", urlEncode("2011-10-01"));
String formattedParameters = calculateStringToSignV2(parameters,
serviceUrl);
String signature = sign(formattedParameters, secretKey);
// Add signature to the parameters and display final results
parameters.put("Signature", urlEncode(signature));
System.out.println(calculateStringToSignV2(parameters,
serviceUrl));
}
private static String calculateStringToSignV2(
Map<String, String> parameters, String serviceUrl)
throws SignatureException, URISyntaxException {
// Sort the parameters alphabetically by storing
// in TreeMap structure
Map<String, String> sorted = new TreeMap<String, String>();
sorted.putAll(parameters);
// Set endpoint value
URI endpoint = new URI(serviceUrl.toLowerCase());
// Create flattened (String) representation
StringBuilder data = new StringBuilder();
//data.append("POST\n");
data.append(endpoint.getHost());
data.append("\n/Products/2011-10-01");
data.append("\n");
Iterator<Entry<String, String>> pairs =
sorted.entrySet().iterator();
while (pairs.hasNext()) {
Map.Entry<String, String> pair = pairs.next();
if (pair.getValue() != null) {
data.append( pair.getKey() + "=" + pair.getValue());
}
else {
data.append( pair.getKey() + "=");
}
// Delimit parameters with ampersand (&)
if (pairs.hasNext()) {
data.append( "&");
}
}
return data.toString();
}
/*
* Sign the text with the given secret key and convert to base64
*/
private static String sign(String data, String secretKey)
throws NoSuchAlgorithmException, InvalidKeyException,
IllegalStateException, UnsupportedEncodingException {
Mac mac = Mac.getInstance(ALGORITHM);
mac.init(new SecretKeySpec(secretKey.getBytes(CHARACTER_ENCODING),
ALGORITHM));
byte[] signature = mac.doFinal(data.getBytes(CHARACTER_ENCODING));
String signatureBase64 = new String(Base64.encodeBase64(signature),
CHARACTER_ENCODING);
return new String(signatureBase64);
}
private static String urlEncode(String rawValue) {
String value = (rawValue == null) ? "" : rawValue;
String encoded = null;
try {
encoded = URLEncoder.encode(value, CHARACTER_ENCODING)
.replace("+", "%20")
.replace("*", "%2A")
.replace("%7E","~"); ;
} catch (UnsupportedEncodingException e) {
System.err.println("Unknown encoding: " + CHARACTER_ENCODING);
e.printStackTrace();
}
return encoded;
}
}
Code Output:
AWSAccessKeyId=&Action=GetMatchingProductForId&SellerId=&Signature=ehjKNnTB5vhrOW3J1yWSz2T7c%3D&SignatureMethod=HmacSHA256&SignatureVersion=2&SubmittedFromDate=2013-05-01T12%3A00%3A00Z&Timestamp=2013-05-02T16%3A00%3A00Z&Version=2011-10-01
Mulesoft Version: 7.11.1
Application XML Detail:
<?xml version="1.0" encoding="UTF-8"?>
<mule xmlns:http="http://www.mulesoft.org/schema/mule/http" xmlns:ee="http://www.mulesoft.org/schema/mule/ee/core"
xmlns="http://www.mulesoft.org/schema/mule/core"
xmlns:doc="http://www.mulesoft.org/schema/mule/documentation" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.mulesoft.org/schema/mule/core http://www.mulesoft.org/schema/mule/core/current/mule.xsd
http://www.mulesoft.org/schema/mule/ee/core http://www.mulesoft.org/schema/mule/ee/core/current/mule-ee.xsd
http://www.mulesoft.org/schema/mule/http http://www.mulesoft.org/schema/mule/http/current/mule-http.xsd">
<flow name="awsFlow" doc:id="eeb85ef5-48cb-4c41-94ba-0e97a0765021" >
<scheduler doc:name="Scheduler" doc:id="f21548f8-1a12-4efa-adf8-27988ac587c5" >
<scheduling-strategy >
<fixed-frequency />
</scheduling-strategy>
</scheduler>
<ee:transform doc:name="Timestamp" doc:id="457efcd6-1388-49fe-88a8-f3d781d17593" >
<ee:message >
</ee:message>
<ee:variables >
<ee:set-variable variableName="requestmws" ><![CDATA[%dw 2.0
output application/json
fun getFormattedDate()=(now() >> "UTC") as String {format: "YYYY-MM-dd"} ++ "T" ++ (now() >> "UTC") as String {format: "HH:mm:ss"} ++ "Z"
---
{
myDate:"mws.amazonservices.com/Products/2011-10-01?AWSAccessKeyId=AKIAI56GX43PIHX4C7XA&Action=GetMatchingProductForId&IdList.Id.1=9781933988665&IdType=EAN&MarketplaceId=ATVPDKIKX0DER&SellerId=A28MSXET37R4N7&SignatureMethod=HmacSHA256&SignatureVersion=2&Version=2011-10-01&Timestamp=" ++ getFormattedDate() replace (':') with ('%3A')
}]]></ee:set-variable>
</ee:variables>
</ee:transform>
<ee:transform doc:name="Transform Message" doc:id="5b556411-1a0a-4d31-b536-48245baf3e0e" >
<ee:message >
</ee:message>
<ee:variables >
<ee:set-variable variableName="signature" ><![CDATA[%dw 2.0
import dw::Crypto
output application/json
---
{ "HMACWith" : Crypto::HMACWith("c4AL2hA6TQQ+vhiAti7OHQI10g7Q9bvOzVHfHOEn" as Binary, vars.requestmws.myDate as Binary, "HmacSHA256") }]]></ee:set-variable>
</ee:variables>
</ee:transform>
<ee:transform doc:name="Transform Message" doc:id="ef709e54-4f12-4db8-9088-9ccb203fda07">
<ee:message>
<ee:set-payload><![CDATA[%dw 2.0
output application/java
---
{
b : vars.requestmws.myDate ++ "&Signature=" ++ vars.signature.HMACWith
}]]></ee:set-payload>
</ee:message>
</ee:transform>
<http:request method="POST" doc:name="Request" doc:id="9301bca2-067f-48a1-badc-4dd6c03a288d" url='#["https://" ++ payload.b]'>
<http:headers ><![CDATA[#[output application/java
---
{
"User-Agent" : "Java/1.8.0_201",
"Content-Type" : "text/xml"
}]]]></http:headers>
</http:request>
<error-handler >
<on-error-continue enableNotifications="true" logException="true" doc:name="On Error Continue" doc:id="27be6630-7439-43c9-86b5-c53c6693f0c7" type="ANY">
<logger level="INFO" doc:name="Logger" doc:id="077e3a7c-902a-48bc-aa8d-6a18af941487" message="#[message]"/>
</on-error-continue>
</error-handler>
</flow>
</mule>
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
由于您显然是在 Mule 4 的某个版本中执行,因此您可以使用 DataWeave 内置函数构建相同的 URL。
例如, HMACWith() 函数将在一步。
除非你有硬性要求在 Java 中实现这一点,否则你可以使用 HTTP 请求 操作您只需添加在 DataWeave 表达式中构建的查询参数,它将负责编码和执行 HTTP 请求的所有实现细节。
Since you are apparently executing in some release of Mule 4, you could build the same URL using DataWeave builtin functions.
For example the HMACWith() function will create the signature in one step.
Unless you have hard requirements to implement this in Java, you can just use the HTTP Request operation you can just add the query parameters you build in DataWeave expressions and it will take care of encoding and all the implementation details of performing the HTTP request.