naver / volley-extensions

Volley Extensions v2.0.0. ( Volleyer, Volley requests, Volley caches, Volley custom views )
134 stars 34 forks source link

Base64 decode #3

Open ncanella opened 9 years ago

ncanella commented 9 years ago

Hi, my http response is encoded in Base64. How can I decode response before parsing it? I want use Json parser, using the method "withTargetClass".

My response could be like this: eyJyZXN1bHQiOnRydWV9

Thanks

ncoolz commented 9 years ago

The easiest way is that you create your own interceptor class for an NetworkResponseParser like below,

public class Base64DecodeInterceptor implements NetworkResponseParser {

    private static final int DEFAULT_DECODE_FLAGS = Base64.DEFAULT;

    private NetworkResponseParser delegate;
    private int decodeFlags;

    public Base64DecodeInterceptor(NetworkResponseParser delegate) {
        this(delegate, DEFAULT_DECODE_FLAGS);
    }

    public Base64DecodeInterceptor(NetworkResponseParser delegate, int decodeFlags) {
        Assert.notNull(delegate, "Delegate");
        this.delegate = delegate;
        this.decodeFlags = decodeFlags;
    }

    @Override
    public <T> Response<T> parseNetworkResponse(NetworkResponse response, Class<T> clazz) {
        Assert.notNull(response, "NetworkResponse");
        Assert.notNull(clazz, "Target class token");

        // decode body of a response
        byte[] decodedData = decodeResponse(response); 
        NetworkResponse newResponse = createNetworkResponse(response.statusCode, decodedData, response.headers, response.notModified);
        return delegate.parseNetworkResponse(newResponse, clazz);
    }

    private byte[] decodeResponse(NetworkResponse response) {
        if (response.data == null) {
            return "".getBytes();
        }

        return Base64.decode(response.data, decodeFlags);
    }

    private NetworkResponse createNetworkResponse(final int statusCode, final byte[] data, final Map<String, String> headers,
            final boolean notModified) {
        NetworkResponse networkResponse = new NetworkResponse(statusCode, data, headers, notModified);
        return networkResponse;
    }

}

You can copy this code and use it without any modification.

As you can see, this class is a wrapper class, so you have to create an original parser, and wrap it.


// Create a jackson 1.x parser. If you use jackson 2.x library, create Jackson2NetworkResponseParser instead.
NetworkResponseParser parser = new JacksonNetworkResponseParser();
// Create an interceptor.
NetworkResponseParser interceptor = new Base64DecodeInterceptor(parser);

This is done. You can now use the interceptor by calling withResponseParser(interceptor).


         volleyer(rq).get(url)
                    .withTargetClass(SomeJsonModel.class)
                    .withNetworkResponseParser(interceptor)
                    .withListener(listener)
                    .execute();

I think that it will be nice to provide some new API for these cases. I'll consider to apply new API on next version.

ncoolz commented 9 years ago

If all of responses are encoded in base64, i recommend you to set the interceptor as default parser.

RequestCreator creator = DefaultVolleyerConfigurationFactory.createRequestCreator();
RequestExecutor executor = DefaultVolleyerConfigurationFactory.createRequestExecutor();
ErrorListener errorListener = DefaultVolleyerConfigurationFactory.createErrorListener();

// Create a new VolleyerConfiguration       
VolleyerConfiguration configuration = new VolleyerConfiguration(creator,
                                                                executor,
                                                                interceptor /* interceptor as default parser */,
                                                                errorListener);

// volleyer settings
volleyer(requestQueue).settings()
                    .setConfiguration(configuration)
                    .done();