きょこみのーと

技術に関係ないほうのブログ

Volleyでjson文字列をgzipに圧縮したreponseに対応してみた

タイトルに全部書いてしまった。

httpstatus200の独自仕様のエラーも起こせるようにしてみました。

ソースコードは以下です。

/**
 * カスタマイズしたJsonRequestです。
 * JsonPullPaserに対応しています。
 * また、json文字列をgzipで圧縮したデータも扱えます。
 * 
 * @author kyokomi
 *
 * @param <JsonData>
 */
public abstract class CustomJsonRequest<JsonData> extends Request<JsonData> {
    
    private static final String GZIP_CONTENT_TYPE = "application/gzip;charset=UTF-8";
    
    private final Listener<JsonData> mListener;
    
    /**
    * コンストラクタ
    * @param method
    * @param url
    * @param listener
    * @param errorListener
    */
    public CustomJsonRequest(int method, String url, Listener<JsonData> listener, ErrorListener errorListener) {
        super(method, url, errorListener);
        mListener = listener;
    }
    /**
    * コンストラクタ
    * @param url
    * @param listener
    * @param errorListener
    */
    public CustomJsonRequest(String url, Listener<JsonData> listener, ErrorListener errorListener) {
        super(Method.GET, url, errorListener);
        mListener = listener;
    }
    
    @Override
    protected void deliverResponse(JsonData response) {
        mListener.onResponse(response);
    }
    
    /**
     * Json文字列からJsonDataに変換するルールを指定してください。
     * 
     * @param responseDataJsonStr Json文字列
     * @return JsonData
     * @throws VolleyError
     */
    protected abstract JsonData parseNetworkResponseDataJsonStr(String responseDataJsonStr) throws VolleyError;
    
    /**
    * エラー検証。
    * 通信ステータスは正常だがレスポンスのjsonデータを見てエラーを発生させたり詳細なエラーに置き換えたりしてください
    * @param jsonData
    * @throws VolleyError 
    */
    protected void validationNetworkResponseJsonData(JsonData jsonData) throws VolleyError {
        return;
    }
    
    @Override
    protected Response<JsonData> parseNetworkResponse(NetworkResponse response) {
        try {
            // Jsonを文字列に変換します
            String jsonString = null;
            
            String contentType = response.headers.get(HTTP.CONTENT_TYPE);
            // ContentTypeが、もしgzipなら解凍する
            if (contentType.equalsIgnoreCase(GZIP_CONTENT_TYPE)) {
                GZIPInputStream zis = new GZIPInputStream(new BufferedInputStream(new ByteArrayInputStream(response.data)));
                try {
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    byte[] buffer = new byte[1024];
                    int count;
                    while ((count = zis.read(buffer)) != -1) {
                        baos.write(buffer, 0, count);
                    }
                    byte[] bytes = baos.toByteArray();
                    jsonString = new String(bytes);
                    baos.close();
                } finally {
                    zis.close();
                }
            } else {
                jsonString = new String(response.data, 
                        HttpHeaderParser.parseCharset(response.headers));   
            }
            
            // Jsonを生成
            JsonData jsonData = parseNetworkResponseDataJsonStr(jsonString);
            // httpStatus200とかでもエラーが入ってるときもあるので(想定しているエラー)
            validationNetworkResponseJsonData(jsonData);
            return Response.success((jsonData), HttpHeaderParser.parseCacheHeaders(response));
        } catch (UnsupportedEncodingException e) {
            return Response.error(new ParseError(e));
        } catch (IOException e) {
            return Response.error(new ParseError(e));
        } catch (VolleyError e) {
            return Response.error(e);
        }
    }
}

Volleyおもしろい!