在 Retrofit 中的请求正文之前添加字符串
Adding string before request body in Retforit
我想在 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);
这是来自登录的代码 activity:
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) {
}
})
);
首先,如果您想在每个请求之前添加字符串,可以使用 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"}}}
最后,我建议您使用包装器 class UserData 将 "data=" 封装在请求字符串中。
我使用 Retrofit 2.0 beta 2。
祝你好运!
我想在 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);
这是来自登录的代码 activity:
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) {
}
})
);
首先,如果您想在每个请求之前添加字符串,可以使用 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"}}}
最后,我建议您使用包装器 class UserData 将 "data=" 封装在请求字符串中。
我使用 Retrofit 2.0 beta 2。
祝你好运!