Amazon Product Advertising APIがjsonベースの5.0に移行することが発表されました。
Amazonが提供しているSDKを利用していない場合は、APIのリクエストのインターフェースがXMLからJSONに変わるので、コードの書き換えは結構面倒です。
Amazonの公式ページでもSDKを使用しないバージョンのサンプルコードが公開されていますが、ApacheのHttpComponentsのライブラリとjsonのライブラリが依存関係に含まれていたので、とにかくAPIを動かしてみたい人向けに標準のJDKだけで動作するサンプルコードを書きました。
(ただし実運用ではJacksonやGSONなど、何らかのjsonライブラリは必須です。)
Amazonが提供しているSDKを利用していない場合は、APIのリクエストのインターフェースがXMLからJSONに変わるので、コードの書き換えは結構面倒です。
Amazonの公式ページでもSDKを使用しないバージョンのサンプルコードが公開されていますが、ApacheのHttpComponentsのライブラリとjsonのライブラリが依存関係に含まれていたので、とにかくAPIを動かしてみたい人向けに標準のJDKだけで動作するサンプルコードを書きました。
(ただし実運用ではJacksonやGSONなど、何らかのjsonライブラリは必須です。)
package com.dukesoftware.amazon;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.util.Map;
import java.util.Map.Entry;
import java.util.TreeMap;
// Java8で動くように、あえてvarなどのJava8では使えないJava機能は未使用
// スクラッチパッドを使うと便利
// https://webservices.amazon.co.jp/paapi5/scratchpad/
public class AmazonProductAdvertisingApiV5 {
public static void main(String[] args) {
// request生成部分はJacksonやGSONなどのライブラリを使用するのが現実的
String jsonRequest = "{"
+ "\"PartnerTag\":\"something-xx\",\"PartnerType\":\"Associates\"," // 固定値。PartnerTang部分は登録してあるタグ
+ "\"ItemIds\":[\"4621303252\"]," // 使用するAPIによって異なる
+ "\"Resources\":[\"ItemInfo.Title\"]" // APIから取得したい項目
+ "}";
System.out.println(jsonRequest);
String jsonResponse = request(
jsonRequest,
"/paapi5/getitems", // 使用するAPIのパス
"com.amazon.paapi5.v1.ProductAdvertisingAPIv1.GetItems" // x-amz-targetで渡すAPIの識別子
);
System.out.println(jsonResponse);
// Jsonをパースしてオブジェクトに変換して、実アプリケーションで利用
}
public static String request(String requestPayload, String path, String targetApi)
{
String host = "webservices.amazon.co.jp";
String region = "us-west-2";
String accessKey = "<access-key>";
String secretKey = "<secret-key>";
@SuppressWarnings("serial")
TreeMap<String, String> headers = new TreeMap<String, String>(){{
put("host", host);
put("content-type", "application/json; charset=utf-8");
put("x-amz-target", targetApi);
put("content-encoding", "amz-1.0");
}};
// https://webservices.amazon.co.jp/paapi5/documentation/without-sdk.html
// で提供されているAWSV4Authクラスを利用
AWSV4Auth awsv4Auth = new AWSV4Auth.Builder(accessKey, secretKey)
.path(path)
.region(region)
.service("ProductAdvertisingAPI")
.httpMethodName("POST")
.headers(headers)
.payload(requestPayload)
.build();
Map<String, String> header = awsv4Auth.getHeaders();
try {
System.out.println("Send Request to Product Advertising API.");
String result = sendPostRequest("https://" + host + path, requestPayload, header, 3000, "UTF-8");
System.out.println("Successfully received response from Product Advertising API.");
return result;
} catch (IOException e) {
e.printStackTrace();
}
System.err.println("Failed to receive response from Product Advertising API.");
return null;
}
// 文字列を指定したURLへPOSTするメソッド
private static String sendPostRequest(String urlString, String payload, Map<String, String> headers, int timeout, String charset) throws IOException
{
URL url = new URL(urlString);
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
conn.setDoOutput(true);
conn.setRequestMethod("POST");
conn.setConnectTimeout(timeout);
conn.setReadTimeout(timeout);
for(Entry<String, String> entry : headers.entrySet())
{
conn.setRequestProperty(entry.getKey(), entry.getValue());
}
try(DataOutputStream out = new DataOutputStream(conn.getOutputStream()))
{
out.write(payload.getBytes(StandardCharsets.UTF_8));
}
if(conn.getResponseCode() == 200)
{
return readAsString(conn.getInputStream(), charset);
}
return readAsString(conn.getErrorStream(), charset);
}
private static String readAsString(InputStream is, String charsetName) throws IOException {
try {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
byte[] buffer = new byte[1024];
for (int bytes = 0 ;(bytes = is.read(buffer)) != -1; )
{
baos.write(buffer, 0, bytes);
}
baos.flush();
return baos.toString(charsetName);
}
finally {
is.close();
}
}
}
コメント