/var/log/messages

debugging with sixth sense

Multipart Form-data でバイナリ送信

送付するバイナリ (画像) のサイズは小さい前提だったので volley を使いました。ググりながら実装してたのですがばっちりビンゴ、なエントリが無かったようなので控えを残しておこうと思った次第です。

以下な Request クラスの拡張を作っています。ファイル名のあたり、若干微妙。

private class MultipartRequest extends Request<String> {

    private MultipartEntityBuilder builder = MultipartEntityBuilder.create();
    private HttpEntity mEntity;
    private final com.android.volley.Response.Listener<String> mListener;
    private final Map<String, String> mStringparts;
    private final Map<String, File> mBinaryparts;

    public MultipartRequest(String Uri, 
        Listener<String> listener,
        ErrorListener errorListener,
        Map<String, String> stringParts, 
        Map<String, File> binaryParts) {

        super(Method.POST, Uri, errorListener);

        mListener = listener;
        mStringparts = stringParts;
        mBinaryparts = binaryParts;

        buildMultipartEntity();
    }

    private void buildMultipartEntity() {
        builder.setMode(HttpMultipartMode.BROWSER_COMPATIBLE);
        builder.setCharset(Charset.forName("UTF-8"));
        ContentType textContentType = ContentType.create("text/plain", "UTF-8");

        for(Map.Entry<String, String> entry : mStringparts.entrySet()) {
            builder.addTextBody(entry.getKey(), entry.getValue(), textContentType);
        }

        for(Map.Entry<String, File> entry : mBinaryparts.entrySet()) {
            builder.addBinaryBody(entry.getKey(), entry.getValue(), ContentType.create("image/jpeg"), mFilename + ".jpg");

        mEntity = builder.build();
    }

    public String getBodyContentType() {
        return mEntity.getContentType().getValue();
    }

    public byte[] getBody() throws AuthFailureError {
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        try {
            mEntity.writeTo(bos);
        } catch (IOException e) {
            Log.e(TAG, "IOException writing to ByteArrayOutputStream");
        }
        return bos.toByteArray();
    }

    protected Response<String> parseNetworkResponse(NetworkResponse response) {
        return Response.success(response, getCacheEntry());
    }

    protected void deliverResponse(String response) {
        mListener.onResponse(response);
    }
}

あとはパラメータとかリスナを作ってあげて

MultipartRequest myRequest = new MultipartRequest(url, myListener,
        myErrorListener, params, files);

してオブジェクトを queue qjnil add してあげれば OK です。

もう少し

ポイントとしては

  • MultipartEntityBuilder クラスを使ってパラメータをセット
  • パラメータを add する時には ContentType も指定

というあたりになるのかどうか。

Comments