天天看點

亞馬遜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;
    }