我计划使用Retrofit制作一个公共服务类,
@GET
Call<ResponseBody> makeGetRequest(@Url String url);
@POST
Call<ResponseBody> makePostRequest(@Url String url, @Body RequestBody parameters);
在这段代码中,我需要传递(ResponseBody)作为动态JSON POJO类名,如LoginRes
比如说,
Call<LoginRes> // But this class will be dynamic
我将通过ResponseBody,但ResponseBody不知道我想要哪个类。
为什么我想要这个因为,结果之后
gson.fromJson(response, LoginRes.class);
所以,在从Retrofit获得结果后,我们再次需要转换为gson.fromJson。
所以我想将动态响应作为Retrofit传递,以便根据我的pojo类响应,
我知道当我传递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);
这就是我称之为服务的方式。
如果我不清楚解释我的问题,请告诉我。
等待一些好的回应和建议。
谢谢Madhav
这有点棘手,但您需要使用自定义Retrofit Converter Factory和自定义GsonBuilder,它使用自定义JsonDeserializer。
此外,您应该定义一个使用CustomJsonDeserializer的接口(在我的示例中为CustomResonse
)。这不是必需的,但是否则Deserializer将用于每个请求。
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();
}
}
由于很多用户给出了DOWN VOTE,我已经自己解决了这个问题,
处理GET,POST或OTHER方法像这样,
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);
}