改造动态 ResponseBody
Retrofit Dynamic ResponseBody
我计划使用 Retrofit 制作一项通用服务 class,
@GET
Call<ResponseBody> makeGetRequest(@Url String url);
@POST
Call<ResponseBody> makePostRequest(@Url String url, @Body RequestBody parameters);
在此代码中,我需要将 (ResponseBody) 作为动态 JSON POJO class 名称传递,例如 LoginRes
举个例子,
Call<LoginRes> // But this class will be dynamic
我将传递 ResponseBody,但 ResponseBody 不知道我想选择哪个 class。
为什么我想要这个因为,在结果之后
gson.fromJson(response, LoginRes.class);
因此,从 Retrofit 获得结果后,我们再次需要转换为 gson.fromJson。
所以我想将动态响应作为 Retrofit 传递,以便它根据我的 pojo 进行响应 class,
我知道当我传递 LoginRes 而不是 ResponseBody 时这工作正常,因为我已经告诉 Response 我们需要 LoginRes 中的响应。
所以如果我通过
Call<LoginRes> // if i pass this way its working fine no need to convert my response i can access my all properties from that LoginRes class directly.
这是我调用 Web 服务的示例。
Call<ResponseBody> call = apiService.makePostRequest("/Buyer/LoginApp", requestBody);
这就是我调用服务的方式。
如果我对问题的解释不清楚,请告诉我。
等待对此的一些好的回应和建议。
谢谢
马达夫
这有点棘手,但您需要使用带有自定义 GsonBuilder 的自定义 Retrofit Converter Factory,后者使用自定义 JsonDeserializer。
此外,您应该定义一个使用 CustomJsonDeserializer 的接口(CustomResonse
在我的示例中)。这不是必需的,但反序列化器会用于 每个 请求。
public class CustomConverterFactory {
public static GsonConverterFactory create() {
return GsonConverterFactory.create(createGsonCustomDeserializer());
}
public static Gson createGsonCustomJsonDeserializer() {
return new GsonBuilder()
.registerTypeAdapter(CustomResponse.class, new CustomJsonDeserializer())
.serializeNulls()
.create();
}
}
对于解串器:
public class CustomJsonDeserializer implements JsonDeserializer<CustomResponse> {
@Override
public CustomResponse deserialize(final JsonElement json, final Type typeOfT,
final JsonDeserializationContext context) throws JsonParseException {
if (json.isJsonObject()) {
JsonObject jsonObject = json.getAsJsonObject();
// Here you have to distinguish your class somehow
// Maybe read some Json field from your response
if (jsonObject.has("name")) {
JsonElement classes = jsonObject.get("name");
...
return context.deserialize(json, MyName.class);
}
...
// Default fallback: Deserialize as a fallback object
return context.deserialize(json, MyFallback.class);
} else {
throw new IllegalStateException();
}
}
Since so many users given a DOWN VOTE, I have already solved this
question by my self,
处理 GET,POST 或像这样的其他方法,
if (methodType.equalsIgnoreCase(CommonConfig.WsMethodType.GET)) {
apicall = getClient(CommonConfig.WsPrefix).create(ApiInterface.class).makeGetRequest(url + CommonConfig.getQueryString(new Gson().toJson(requestBody)), getAllHeader);
} else if (methodType.equalsIgnoreCase(CommonConfig.WsMethodType.POST)) {
apicall = getClient(CommonConfig.WsPrefix).create(ApiInterface.class).makePostRequest(url, RequestBody.create(MediaType.parse("application/json"), new Gson().toJson(requestBody)), getAllHeader);
}
像这样处理响应。
apicall.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
}
改造代码
private Retrofit getClient(String WsPrefix) {
//TODO 60 to 30 second at everywhere
OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
.connectTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.build();
retrofit = new Retrofit.Builder()
.baseUrl(WsPrefix)
.client(okHttpClient)
.build();
return retrofit;
}
通用接口
interface ApiInterface {
@GET
Call<ResponseBody> makeGetRequest(@Url String url, @HeaderMap() Map<String, String> header);
@POST
Call<ResponseBody> makePostRequest(@Url String url, @Body RequestBody requestBody, @HeaderMap() Map<String, String> header);
}
ApiCallback
public interface ApiCallback {
void success(String responseData);
void failure(String responseData);
}
我计划使用 Retrofit 制作一项通用服务 class,
@GET
Call<ResponseBody> makeGetRequest(@Url String url);
@POST
Call<ResponseBody> makePostRequest(@Url String url, @Body RequestBody parameters);
在此代码中,我需要将 (ResponseBody) 作为动态 JSON POJO class 名称传递,例如 LoginRes
举个例子,
Call<LoginRes> // But this class will be dynamic
我将传递 ResponseBody,但 ResponseBody 不知道我想选择哪个 class。
为什么我想要这个因为,在结果之后
gson.fromJson(response, LoginRes.class);
因此,从 Retrofit 获得结果后,我们再次需要转换为 gson.fromJson。
所以我想将动态响应作为 Retrofit 传递,以便它根据我的 pojo 进行响应 class,
我知道当我传递 LoginRes 而不是 ResponseBody 时这工作正常,因为我已经告诉 Response 我们需要 LoginRes 中的响应。
所以如果我通过
Call<LoginRes> // if i pass this way its working fine no need to convert my response i can access my all properties from that LoginRes class directly.
这是我调用 Web 服务的示例。
Call<ResponseBody> call = apiService.makePostRequest("/Buyer/LoginApp", requestBody);
这就是我调用服务的方式。
如果我对问题的解释不清楚,请告诉我。
等待对此的一些好的回应和建议。
谢谢 马达夫
这有点棘手,但您需要使用带有自定义 GsonBuilder 的自定义 Retrofit Converter Factory,后者使用自定义 JsonDeserializer。
此外,您应该定义一个使用 CustomJsonDeserializer 的接口(CustomResonse
在我的示例中)。这不是必需的,但反序列化器会用于 每个 请求。
public class CustomConverterFactory {
public static GsonConverterFactory create() {
return GsonConverterFactory.create(createGsonCustomDeserializer());
}
public static Gson createGsonCustomJsonDeserializer() {
return new GsonBuilder()
.registerTypeAdapter(CustomResponse.class, new CustomJsonDeserializer())
.serializeNulls()
.create();
}
}
对于解串器:
public class CustomJsonDeserializer implements JsonDeserializer<CustomResponse> {
@Override
public CustomResponse deserialize(final JsonElement json, final Type typeOfT,
final JsonDeserializationContext context) throws JsonParseException {
if (json.isJsonObject()) {
JsonObject jsonObject = json.getAsJsonObject();
// Here you have to distinguish your class somehow
// Maybe read some Json field from your response
if (jsonObject.has("name")) {
JsonElement classes = jsonObject.get("name");
...
return context.deserialize(json, MyName.class);
}
...
// Default fallback: Deserialize as a fallback object
return context.deserialize(json, MyFallback.class);
} else {
throw new IllegalStateException();
}
}
Since so many users given a DOWN VOTE, I have already solved this question by my self,
处理 GET,POST 或像这样的其他方法,
if (methodType.equalsIgnoreCase(CommonConfig.WsMethodType.GET)) {
apicall = getClient(CommonConfig.WsPrefix).create(ApiInterface.class).makeGetRequest(url + CommonConfig.getQueryString(new Gson().toJson(requestBody)), getAllHeader);
} else if (methodType.equalsIgnoreCase(CommonConfig.WsMethodType.POST)) {
apicall = getClient(CommonConfig.WsPrefix).create(ApiInterface.class).makePostRequest(url, RequestBody.create(MediaType.parse("application/json"), new Gson().toJson(requestBody)), getAllHeader);
}
像这样处理响应。
apicall.enqueue(new Callback<ResponseBody>() {
@Override
public void onResponse(Call<ResponseBody> call, Response<ResponseBody> response) {
}
@Override
public void onFailure(Call<ResponseBody> call, Throwable t) {
}
}
改造代码
private Retrofit getClient(String WsPrefix) {
//TODO 60 to 30 second at everywhere
OkHttpClient okHttpClient = new OkHttpClient().newBuilder()
.connectTimeout(60, TimeUnit.SECONDS)
.readTimeout(60, TimeUnit.SECONDS)
.writeTimeout(60, TimeUnit.SECONDS)
.build();
retrofit = new Retrofit.Builder()
.baseUrl(WsPrefix)
.client(okHttpClient)
.build();
return retrofit;
}
通用接口
interface ApiInterface {
@GET
Call<ResponseBody> makeGetRequest(@Url String url, @HeaderMap() Map<String, String> header);
@POST
Call<ResponseBody> makePostRequest(@Url String url, @Body RequestBody requestBody, @HeaderMap() Map<String, String> header);
}
ApiCallback
public interface ApiCallback {
void success(String responseData);
void failure(String responseData);
}