Apexからmultipart/form-data形式でHTTPリクエストを行うときは

自前でBodyをゴリゴリ書いていく必要があるのですが、その際にファイルなどのバイナリデータを

含めるときの対応に関して書いていきます。

パターン1: HTTP Request Bodyをテキストで送信

受信側(API提供側)でContent-Transfer-Encoding: base64に対応しているケースで利用可能です。

Apexだと以下のようなコードになります(Boxのサンプル)

multipart/form-dataの形式でBase64エンコードしたバイナリデータをBodyに載せただけで

非常にシンプルに実装できます。

パターン2: HTTP Request Bodyをバイナリとして送信

受信側がContent-Transfer-Encoding: base64に対応していないパターンになります。

Apexでは現時点ではバイナリの連結が出来ません。

なのでバイナリを連結するためにはBase64エンコードした文字列を”うまい具合”に連結したものを

最後にBase64デコードする必要があります。

ただし、Base64エンコードは6bit毎に4文字ずつ(=3byte)エンコーディングしていくので

余りが出る場合は=によるパディングがされて

base64エンコードした文字列の桁数は4の倍数になります。

そのためパディングも含めて連結してしまうと、デコーディングが出来なくなってしまいます。

つまり、Apexでバイナリ連結するためにはBase64エンコードした結果がパディングを含まない

つまり、もとのバイナリのバイト数が3の倍数である必要があります。

 

Apexのサンプルコードは以下になります。

getMultiPartBodyメソッドは参考URL丸パクリです。

参考URL→http://blog.enree.co/2013/01/salesforce-apex-post-mutipartform-data.html

見ての通り結構面倒ですorz

バイト数を合わせるために元の文字列をスペースでパディングしたり

後続の改行コード(\r\n)を含めたりしてバイト数を調整しているのがミソで

“0K”はbase64デコードすると”\r\n”に”K”は”\r”になるのでbase64エンコードした文字列に

それぞれの文字をアペンドしています。