1、引言
这篇文章主要介绍商品的刊登
2、API介绍
商品的上传主要用的是Feeds API,我们来看一下Feeds的工作流程:
整个操作采用异步的流程:
- 通过 SubmitFeed 操作以及加密标头和所有必需的元数据提交 XML 或库存模板文件,其中包括 FeedType 的值。正如所有提交的亚马逊MWS 内容一样,您还必须将验证信息包含在内。该 SubmitFeed 操作可返回 FeedSubmissionId,而其可用于定期检查上传数据的状态(使用 GetFeedSubmissionList 操作)。
- 如果亚马逊MWS 仍在处理请求,则 FeedProcessingStatus 元素(GetFeedSubmissionList 操作)返回 IN_PROGRESS 的状态。如果处理已完成,则返回 DONE 的状态
- 上传数据处理完成后,您可以通过 GetFeedSubmissionResult 操作来接收处理报告,该处理报告会指明上传数据中的哪些记录已成功处理,而哪些记录已生成错误。请注意:您必须设置 亚马逊MWS用于编写报告的流(提交 GetFeedSubmissionResult 操作时)。使用亚马逊MWS上传数据 API部分客户端库代码(GetFeedSubmissionResult 操作)以创建流。
- 分析处理报告,更正文件中或传送中的错误,然后通过 SubmitFeed 操作重新提交上传数据。不断重复此过程,直到处理报告中不再有错误。当处理报告无任何错误时,传送即完成。
3、思路
上传产品FeedType有几种方式,主要分为xml文件和文本文件,文本文件提交feed类型为 POST_FLAT_FILE_LISTINGS_DATA ,xml文件feed对应的类型为_POST_PRODUCT_DATA_。
文本文件一般是csv、excel或者txt都行,该类型和亚马逊后台刊登商品是一样的,根据分类下载对应的LISTINGS模板然后后台上传
xml文件就是给出的亚马逊xsd规范,生成对应商品的xml文件,据说这是亚马逊推荐的。
作者采用的xml上传,未使用文本文件上传的方式,所以对文件上传的方式不做介绍,主要介绍xml方式。
4、实现
公共参数有三部分参数:
a、开发者帐号参数devlopId,accessKeyId,secretAccessKey
b、亚马逊参数:serviceUrl MarketplaceId
亚马逊分为三个地区北美地区、欧洲地区、远东对应的值都不一样
参考http://docs.developer.amazonservices.com/zh_CN/dev_guide/DG_Endpoints.html
c、卖家授权参数sellerId、authToken
测试上传伪代码(分为三步):
/**
* 第一步 建立请求,上传数据
* 通过 SubmitFeed 操作以及加密标头和所有必需的元数据提交 XML 或库存模板文件,其中包括 FeedType 的值。
* 正如所有提交的亚马逊MWS 内容一样,您还必须将验证信息包含在内。该 SubmitFeed 操作可返回 FeedSubmissionId,
* 而其可用于定期检查上传数据的状态(使用 GetFeedSubmissionList 第二步操作)
* @param filePath xml文件地址
* @param feedType 类型比如上传商品_POST_PRODUCT_DATA_
* @throws IOException
* @throws MarketplaceWebServiceException
* @throws NoSuchAlgorithmException
*/
@Test
public String submitProduct(String filePath,String feedType) throws IOException, MarketplaceWebServiceException, NoSuchAlgorithmException {
MarketplaceWebService service = getClient();
final String merchantId = this.sellerId;
final String sellerDevAuthToken = this.authToken;
final IdList marketplaces = new IdList(Arrays.asList(
this.marketplaceId));
SubmitFeedRequest request = new SubmitFeedRequest();
request.setMerchant(merchantId);
request.setMWSAuthToken(sellerDevAuthToken);
request.setMarketplaceIdList(marketplaces);
request.setContentType(ContentType.TextTabUtf8);
request.setFeedType(feedType);
FileInputStream fileInputStream = new FileInputStream(filePath);
FileInputStream fileInputStream2 = new FileInputStream(filePath);
request.setFeedContent(fileInputStream);
request.setContentMD5(AmazonHeaderMD5Util.computeUploadContentMD5HeaderValue(fileInputStream2));
SubmitFeedResponse response = service.submitFeed(request);
if (response.isSetSubmitFeedResult()) {
SubmitFeedResult submitFeedResult = response
.getSubmitFeedResult();
if (submitFeedResult.isSetFeedSubmissionInfo()) {
String feedSubmissionId = submitFeedResult.getFeedSubmissionInfo().getFeedSubmissionId();
return feedSubmissionId;
}
}
return null;
}
/**
* 第二步
* 调用GetFeedSubmissionList接口方法,将第一步操作返回的FeedSubmissionId值,设置到请求参数 FeedSubmissionIdList中。
* 此刻,获得Amazon的返回结果,我们可以通过FeedSubmissionInfo中FeedProcessingStatus状态来判断数据是否上传完成
* 如果FeedProcessingStatus状态值
* 返回 _IN_PROGRESS_ 的状态。如果数据量大的情况下,我建议大家Sleep 一会,个人建议Sleep时间设置为1—5分钟之间,视个人情况而定。
* 返回 _DONE_ 的状态,说明已经上传成功,接着执行后续操作了
* @throws MarketplaceWebServiceException
*/
@Test
public boolean getFeedSubmissionList(List<String> feedSubmissionIds) throws MarketplaceWebServiceException {
AtomicBoolean isNotDone = new AtomicBoolean(true);
//必须参数
MarketplaceWebService service = getClient();
final String merchantId = this.sellerId;
final String sellerDevAuthToken = this.authToken;
GetFeedSubmissionListRequest request = new GetFeedSubmissionListRequest();
request.setMerchant(merchantId);
request.setMWSAuthToken(sellerDevAuthToken);
if(!CollectionUtils.isEmpty(feedSubmissionIds)){
request.setFeedSubmissionIdList(new IdList(feedSubmissionIds));
}
while (isNotDone.get()) {
GetFeedSubmissionListResponse response = service.getFeedSubmissionList(request);
GetFeedSubmissionListResult result = response.getGetFeedSubmissionListResult();
result.getFeedSubmissionInfoList().forEach(item -> {
if (item.getFeedProcessingStatus().equalsIgnoreCase("_DONE_"))
isNotDone.set(false);
} else {
sleep();
}
});
}
return isNotDone.get();
}
/**
* 第三步
* 在第二步的上传状态返回" _DONE_"之后,我们可以调用GetFeedSubmissionResult方法,
* 设置第一步返回的FeedSubmissionId参数,来获得上传结果信息。
* 上传结果信息包含成功个数,失败的具体信息等。通过核对失败的信息,我们修改后可以继续上传
* 请注意:您必须设置 亚马逊MWS用于编写报告的流(提交 GetFeedSubmissionResult 操作时)。
* 使用亚马逊MWS上传数据 API部分客户端库代码(GetFeedSubmissionResult 操作)以创建流
*/
@Test
public void getFeedSubmissionResult(String feedSubmissionId) throws Exception {
//必须参数
MarketplaceWebService service = getClient();
final String merchantId = this.sellerId;
final String sellerDevAuthToken = this.authToken;
GetFeedSubmissionResultRequest request = new GetFeedSubmissionResultRequest();
OutputStream os = new ByteArrayOutputStream();
request.setFeedSubmissionResultOutputStream(os);
request.setMerchant(merchantId);
request.setMWSAuthToken(sellerDevAuthToken);
request.setFeedSubmissionId(feedSubmissionId);
GetFeedSubmissionResultResponse response = service.getFeedSubmissionResult(request);
if (response.isSetGetFeedSubmissionResultResult()) {
GetFeedSubmissionResultResult result = response.getGetFeedSubmissionResultResult();
//该 GetFeedSubmissionResult 操作可返回上传数据处理报告及所返回 HTTP 正文的 Content-MD5 标头。
//您应计算我们亚马逊MWS 返回给您的报告的 HTTP 正文的 MD5 散列值,并将它与我们返回的 Content-MD5 标头值加以比较。
//如果计算得出的散列值与所返回的散列值不符,则报告正文已在传送过程中损坏。
// 您应放弃此结果,并自动重试请求,但最多不可超过三次。请告知亚马逊MWS 您所接收的报告正文是否已损坏。
// 要获取 Content-MD5 标头的更多相关信息,请参阅亚马逊MWS开发者指南
}
}
public MarketplaceWebService getClient() {
MarketplaceWebServiceConfig config = this.getConfig();
MarketplaceWebService client = new MarketplaceWebServiceClient(accessKeyId,secretAccessKey,appName,appVersion,config);
return client;
}
上传产品是一个异步接口,提交成功(也就是第一步)会返回如下数据:
<?xml version="1.0" encoding="utf-8"?>
<SubmitFeedResponse xmlns="http://mws.amazonaws.com/doc/2009-01-01/">
<SubmitFeedResult>
<FeedSubmissionInfo>
<FeedSubmissionId>2291326430</FeedSubmissionId>
<FeedType>_POST_PRODUCT_DATA_</FeedType>
<SubmittedDate>2009-02-20T02:10:35+00:00</SubmittedDate>
<FeedProcessingStatus>_SUBMITTED_</FeedProcessingStatus>
</FeedSubmissionInfo>
</SubmitFeedResult>
<ResponseMetadata>
<RequestId>75424a38-f333-4105-98f0-2aa9592d665c</RequestId>
</ResponseMetadata>
</SubmitFeedResponse>
拿到FeedSubmissionId值作为参数调用第二步的方法,可以根据FeedProcessingStatus查看第一步上传结果的进度,参考文档http://docs.developer.amazonservices.com/zh_CN/feeds/Feeds_FeedProcessingStatus.html
当第二部状态FeedProcessingStatus为_DONE_的时候调用第三步方法,返回结果如下数据:
成功的结果:
<?xml version="1.0" encoding="UTF-8"?>
<AmazonEnvelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="amzn-envelope.xsd">
<Header>
<DocumentVersion>1.02</DocumentVersion>
<MerchantIdentifier>A38IPBT243LO97</MerchantIdentifier>
</Header>
<MessageType>ProcessingReport</MessageType>
<Message>
<MessageID>1</MessageID>
<ProcessingReport>
<DocumentTransactionID>2291326430</DocumentTransactionID>
<StatusCode>Complete</StatusCode>
<ProcessingSummary>
<MessagesProcessed>1</MessagesProcessed>
<MessagesSuccessful>1</MessagesSuccessful>
<MessagesWithError>0</MessagesWithError>
<MessagesWithWarning>0</MessagesWithWarning>
</ProcessingSummary>
</ProcessingReport>
</Message>
</AmazonEnvelope>
有错误的结果:
<?xml version="1.0" encoding="UTF-8"?>
<AmazonEnvelope xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="amzn-envelope.xsd">
<Header>
<DocumentVersion>1.02</DocumentVersion>
<MerchantIdentifier>A28TWGEAZIBB9N</MerchantIdentifier>
</Header>
<MessageType>ProcessingReport</MessageType>
<Message>
<MessageID>1</MessageID>
<ProcessingReport>
<DocumentTransactionID>2291326430</DocumentTransactionID>
<StatusCode>Complete</StatusCode>
<ProcessingSummary>
<MessagesProcessed>1</MessagesProcessed>
<MessagesSuccessful>0</MessagesSuccessful>
<MessagesWithError>1</MessagesWithError>
<MessagesWithWarning>0</MessagesWithWarning>
</ProcessingSummary>
<Result>
<MessageID>1</MessageID>
<ResultCode>Error</ResultCode>
<ResultMessageCode>8045</ResultMessageCode>
<ResultDescription>错误消息</ResultDescription>
<AdditionalInfo>
<SKU>123</SKU>
</AdditionalInfo>
</Result>
</ProcessingReport>
</Message>
</AmazonEnvelope>
5、总结
整个上传流程大概就是这样,往亚马逊发送数据都是统一用这个feeds的api,只是对应的FeedType不一样,常用的FeedType有如下几种:http://docs.developer.amazonservices.com/zh_CN/feeds/Feeds_FeedType.html
整个流程就是这三步,难点是在于构建你需要的xml参数,下一篇将重点介绍一下,上传产品xml的一些必要参数