改造:如何在POST中发送base64编码的正文请求

时间:2015-10-14 17:25:14

标签: android retrofit

我最近在我的Android应用程序中开始使用Retrofit,这是我添加用户的改装请求:

RestAdapter mRestAdapter =  new RestAdapter.Builder()
        .setEndpoint(SERVER_URL)
        .setLogLevel(RestAdapter.LogLevel.FULL)
        .setRequestInterceptor(new SessionInterceptor())
        .setClient(new OkClient(new OkHttpClient()))
        .build();

@POST("/user/add")
    JsonElement registerUser(@Body User user);

此处User是我想要向服务器注册的用户的模型类。问题是服务器需要Base64.encode()格式的json正文请求。有没有办法使用改造发送Base64编码数据?

我可以想到手动这样做:

String json = gson.toJson(user);
byte[] bytes = Base64.encode(json.getBytes("UTF-8"), Base64.DEFAULT);

然后在请求中传递此内容。但是,我必须手动完成每个POST请求。有没有更清洁的方法来做到这一点。

2 个答案:

答案 0 :(得分:2)

对于一般对象类型(包括String)Retrofit将使用其Converter来序列化该值。在这种情况下,默认情况下使用Gson将主体序列化为JSON。

要上传您希望使用TypedInput的Base64编码数据。这告诉Retrofit您将传递已经序列化的原始主体和相关的Content-Type值。

答案 1 :(得分:1)

这个答案直接适用于Retrofit v2.0,但同样的概念可以适用于早期版本。

一种选择是创建RequestInterceptor。根据您提供的信息,我不太确定每个 POST是否为64位编码。我会假设是这种情况。

public class Base64EncodeRequestInterceptor implements Interceptor {

    @Override
    public Response intercept(Chain chain) throws IOException {
        Request originalRequest = chain.request();
        Request.Builder builder = originalRequest.newBuilder();

        if (originalRequest.method().equalsIgnoreCase(POST)) {
          builder = originalRequest.newBuilder()
              .method(originalRequest.method(), encode(originalRequest.body()));
        }


        return chain.proceed(builder.build());
    }

    private RequestBody encode(RequestBody body) {
        return new RequestBody() {
            @Override
            public MediaType contentType() {
                return body.contentType();
            }

            @Override
            public void writeTo(BufferedSink sink) throws IOException {
                Buffer buffer = new Buffer();
                body.writeTo(buffer);
                byte[] encoded = Base64.encode(buffer.readByteArray(), Base64.DEFAULT);
                sink.write(encoded);
                buffer.close();
                sink.close();
            }
        };
    }
}

此拦截器的作用是检查传入方法是否为POST,如果是,则它将对RequestBody进行base64编码。