改造动态ResponseBody

问题描述 投票:0回答:2

我计划使用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

java android android-studio retrofit retrofit2
2个回答
2
投票

这有点棘手,但您需要使用自定义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();
    }
}

1
投票

由于很多用户给出了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);
}
© www.soinside.com 2019 - 2024. All rights reserved.