天天看点

亚马逊SubmitFeed接口方法实现亚马逊SubmitFeed接口(参考自官方API)

亚马逊SubmitFeed接口(参考自官方API)

商品上传(也可用于订单跟踪,根据FeedType来)

单独的上传流程(下一篇有空再写完整的流程,包括获取上传结果)

有需要可查看亚马逊官方API文档

public class example {
    private static final String CHARACTER_ENCODING = "UTF-8";  //编码方式
    final static String ALGORITHM = "HmacSHA256";    //亚马逊支持的哈希散列

    public static void main(String[] args) throws Exception {
        // 密钥的值,注意要与AWSAccessKeyId区分开,此处是密钥,不是keyid
        String secretKey = "Your secret key";
		//这有两种生成xml模板的方法
		//1.就是直接复制xml模板到本地磁盘
		//2.用String拼接xml,并以流的形式上传文件
		String filePath = "你的文件地址";
		//生成MD5值,本类已从官网摘抄模板方法
		String MD5 = computeContentMD5HeaderValue(new FileInputStream(filePath));
				
        // 请求网点地址
        String serviceUrl = "https://mws.amazonservices.com/";

        // 创建一个存放参数的map
        HashMap<String, String> parameters = new HashMap<String,String>();

        // 添加设置好的参数,urlEncode是一种url地址规范方法
        parameters.put("AWSAccessKeyId", urlEncode("Your Access Key Id"));
        //此处的FeedType有多种,需要的可以参考官网
       (http://docs.developer.amazonservices.com/zh_CN/feeds/Feeds_FeedType.html)
       
        parameters.put("Action", urlEncode("SubmitFeed"));   
        parameters.put("MWSAuthToken", urlEncode("Your MWS Auth Token"));
        parameters.put("SellerId", urlEncode("Your Seller Id"));
        parameters.put("SignatureMethod", urlEncode(ALGORITHM)); //哈希散列
        parameters.put("SignatureVersion", urlEncode("2"));
        //ContentMD5Value这个参数是用来判断上传的数据有没有丢失缺损
        parame.put("ContentMD5Value", urlEncode(md5));
        //这里存放自己获取的即时时间戳
        parameters.put("Timestamp", urlEncode("2013-05-02T16:00:00Z"));
        parameters.put("Version", urlEncode("2009-01-01"));

        // 生成要签名的内容格式
        String formattedParameters = calculateStringToSignV2(parameters,
            serviceUrl);
        //对内容进行签名
        String signature = sign(formattedParameters, secretKey);

        // 添加请求签名的参数
        parameters.put("Signature", urlEncode(signature));
        //对所有参数再排序一遍并以字符串输出
        String sortParam = sortParams(new StringBuilder(), parame);
        //发起http请求,把请求到的数据答应出来,一般是xml格式,记得把回应流转换成json格式
        //其他的格式也可
        //SubmitFeedPost(serviceUrl, sortParama);
        System.out.println(SubmitFeedPost(serviceUrl, sortParama));
       
    }
}
           

submitfeed发送请求(AResult可以换成别的储存结构)

public static AResult SubmitFeedPost(String serviceUrl, String sortParama){
       AResult result = new AResult();
       CloseableHttpClient httpclient = HttpClients.createDefault();
       //封装成一个完整url地址,以及添加请求头
       HttpPost httpPost = new HttpPost(serviceUrl + "?" + sortParama);
       httpPost.addHeader("Host", "mws.amazonservices.com");
       httpPost.addHeader("Content-Type", "text/xml"); //类型参考MWS API
       httpPost.addHeader("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/74.0.3724.8 Safari/537.36");
       httpPost.addHeader("x-amazon-user-agent", "AmazonJavascriptScratchpad/1.0 (Language=Javascript)");
       //注意这个FeedContent是以正文传输,要跟参数区分开,此处是以流的形式上传
   	httpPost.setEntity(new FileEntity(new File(filePath)));
       CloseableHttpResponse response = null;
       try {
           response = httpclient.execute(httpPost);
           HttpEntity responseEntity = response.getEntity();
           InputStream is = responseEntity.getContent();
           AData data= parseXML(is);
           result.setData(data);
       } catch (IOException e) {
           e.printStackTrace();
       } finally {
           try {
               response.close();
               httpclient.close();
           } catch (IOException e) {
               e.printStackTrace();
           }
       }
       return result;
   }
           

生成签名内容格式,此格式存在要求

private static String calculateStringToSignV2(
        Map<String, String> parameters, String serviceUrl)
            throws SignatureException, URISyntaxException {
        // in TreeMap structure
       String v2=null;
        try{
            URI endpoint = new URI(serviceUrl.toLowerCase());
            StringBuilder data = new StringBuilder();
            data.append("POST\n");
            data.append(endpoint.getHost());
            data.append("\n" + new URI(serviceUrl).getPath());
            data.append("\n");
            //调用该方法进行参数的排序以及格式化url地址
            v2= sortParams(data, parameters);
        }catch (Exception e){
            e.printStackTrace();
        }finally {
            return v2;
        }
    }
           

对参数进行排序以及格式化(url地址有序)

public static String sortParams(StringBuilder data, Map<String, String> parameters) {
       Map<String, String> sorted = new TreeMap<String, String>();
       sorted.putAll(parameters);

       Iterator<Map.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() + "=");
           }
           if (pairs.hasNext()) {
               data.append("&");
           }
       }
       return data.toString();
   }
           

对签名内容与密钥一起加密转成base64,这就是参数signature的值

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);
   }
   //要进行url编码,这也是必要的,防止请求地址识别错误
   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;
   }
   //转化请求后返回的数据,AData可以换成HashMap
   private static AData parseXML(InputStream is) {
       JSON xml = new XMLSerializer().readFromStream(is);
       JSONObject jsonObject = JSONObject.fromObject(xml);
       AData data=new AData(jsonObject.toString());
       return data;
   }
           

Content-MD5校验和方法(MWS API),注意是流的形式

//Content-MD5校验和
    public static String computeContentMD5HeaderValue( FileInputStream fis )
            throws IOException, NoSuchAlgorithmException {

        DigestInputStream dis = new DigestInputStream( fis,
                MessageDigest.getInstance( "MD5" ));

        byte[] buffer = new byte[8192];
        while( dis.read( buffer ) > 0 );

        String md5Content = new String(
                org.apache.commons.codec.binary.Base64.encodeBase64(
                        dis.getMessageDigest().digest()) );
        // Effectively resets the stream to be beginning of the file
        // via a FileChannel.
        fis.getChannel().position( 0 );

        return md5Content;
    }