在Retforit中的请求主体之前添加字符串

时间:2015-11-08 06:22:57

标签: android retrofit rx-android

我想在Retrofit请求中在请求体之前添加字符串。 我的意思是:

data={"action":"users.login","data":{"email":"test@gmail.com", "password":"password"}}

但Retofit仅允许请求此类型:

{"action":"users.login","data":{"email":"test@gmail.com", "password":"password"}}

这是我在界面中的方法代码:

@POST("/api")
Observable<RequestResult> loginAction(@Body Request<User> userRequest);

来自登录活动的代码:

User user = new User();
user.setEmail("email");
user.setPassword("password");

    subscription.add(
            service.loginAction(
                    new Request<>("users.login", user))
            .subscribeOn(Schedulers.newThread())
            .observeOn(AndroidSchedulers.mainThread())
            .subscribe(new Observer<RequestResult>() {
                @Override
                public void onCompleted() {
                }
                @Override
                public void onError(Throwable e) {
                }
                @Override
                public void onNext(RequestResult requestResult) {
                }
            })
    );

1 个答案:

答案 0 :(得分:1)

首先,如果您想在每个请求之前添加字符串,可以使用OkHttp interceptor指定它们。

就像这样,

    client.interceptors().add(new Interceptor() {
        @Override
        public Response intercept(Chain chain) throws IOException {
            Request request = chain.request();

            String time = DateUtil.getDefaultDateTime(new Date());


            RequestBody body = request.body();

            String bodyData = "data=";

            if (body != null) {
                Buffer bufferedSink = new Buffer();
                request.body().writeTo(bufferedSink);
                bodyData += bufferedSink.readUtf8();
            }

            String tokenData = AppContext.get(ContextConstant.TOKEN, "");

            String keyData = request.url() + bodyData + time + tokenData;

            String key = Encryption.genKey(keyData);

            String userId = AppContext.get(ContextConstant.CURRENT_USER_ID, "");

            String authorization = Encryption.getHeaderValue(userId, AppContext.getInstance().getUUID());

            Request.Builder requestBuilder = request.newBuilder();

            requestBuilder.header("X-key", key);
            requestBuilder.header("Authorization", authorization.replace("\n", ""));
            requestBuilder.header("X-API-Version", AppConstant.API_VERSION);
            requestBuilder.header("X-Data-version", AppConstant.DATA_VERSION);
            requestBuilder.header("X-Request-Time", time);

            Request okRequest = requestBuilder.build();

            Response response = chain.proceed(okRequest);

            return response;
        }

    });

但是,我只对指定的Header使用这种方式,而不是指定的RequestBody。

其次,如果你使用Gson,(不幸的是,你没有)

        Gson gson = new GsonBuilder()
            .setDateFormat(DateUtil.FORMAT)
            .registerTypeAdapter(User.class, new UserDeserializer())
            .registerTypeAdapter(User.class, new UserSerializer())
            .create();

    Retrofit retrofit = new Retrofit.Builder()
            .baseUrl(AppConstant.HOST)
            .addConverterFactory(GsonConverterFactory.create(gson))
            .client(client)
            .build();

在UserSerializer中,

public class UserSerializer implements JsonSerializer<User> {
@Override
public JsonElement serialize(User src, Type typeOfSrc, JsonSerializationContext context) {
    return new JsonPrimitive("data=" + src.toString());
}

}

我认为它可能是{} ....

{data={"action":"users.login","data":{"email":"test@gmail.com", "password":"password"}}}

最后,我建议你在请求字符串中使用封装“user =”的包装类UserData。

我使用的是Retrofit 2.0 beta 2。

祝你好运!