tanamonの稀に良く書く日記

KEEP CALM AND DRINK BEER

AmazonのProduct Advertising APIのJava版公式サンプルがそのままだと動かない件

Product Advertising APIにあるサンプルを元に、

  • endpoint = "ecs.amazonaws.jp"
  • awsAccessKeyId = ""; // Access Key IDの値
  • awsSecretKey = ""// Secret Access Keyの値

に変更して試してもうまく動かないのです。

エラー

<?xml version="1.0" encoding="UTF-8"?>
<ItemSearchResponse xmlns="http://webservices.amazon.com/AWSECommerceService/2005-10-05">
<OperationRequest>
<HTTPHeaders>
<Header Name="UserAgent" Value="Java/1.6.0_13"></Header>
</HTTPHeaders>
<RequestId>****************************</RequestId>
<Arguments>
<Argument Name="SearchIndex" Value="Blended"></Argument>
<Argument Name="ResponseGroup" Value="Request,Medium"></Argument>
<Argument Name="Timestamp" Value="2009-12-12T17:07:29Z"></Argument>
<Argument Name="Signature" Value="*******************************************************
"></Argument>
<Argument Name="AWSAccessKeyId" Value="*************************"></Argument>
<Argument Name="Service" Value="AWSECommerceService"></Argument>
<Argument Name="Keywords" Value="amazon"></Argument>
<Argument Name="Operation" Value="ItemSearch"></Argument>
</Arguments>
<Errors>
<Error>
<Code>AWS.InvalidParameterValue</Code>
<Message>*******************************************************
は、Signatureの値として無効です。値を変更してから、再度リクエストを実行してください。</Message>
</Error>
<Error>
<Code>AWS.InvalidSignature</Code>
<Message>指定された署名は予測したリクエスト署名と一致しません。 AWSシークレットアクセスキーと署名方法を確認してください。 詳細については、サービスに関するドキュメントを参照してください。</Message>
</Error>
</Errors>
</OperationRequest>
</ItemSearchResponse>

リクエスト署名が一致しないらしいです。
3回くらい確認したんだけどだめでした。

何が原因?

注意深くレスポンス内容をみるとわかる。

<Argument Name="Signature" Value="*******************************************************
"></Argument>

こことか、

<Message>*******************************************************
は、Signatureの値として無効です。値を変更してから、再度リクエストを実行してください。</Message>

ここ。

どうやらSignatureの最後に改行コードが入っているらしい。

解決方法

Base64 encoder = new Base64();
signature = new String(encoder.encode(rawHmac));

こいつが原因でした。以下のように

Base64 encoder = new Base64(0);
signature = new String(encoder.encode(rawHmac));

Base64のコンストラクタの第一引数(linelength)に0を渡すようにすると改行しないようになります。


これでサンプルコードで結果が正常に返ってくるようになります。