有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java使用改型2获取和获取未知数据集

改型是一个很棒的库,使用和维护都很简单,但我的情况不同,正如我们所知,我们应该应用创建改型api和相应响应的各个阶段

改装实例:

retrofit = new Retrofit.Builder()
                .baseUrl(url)
                .addConverterFactory(GsonConverterFactory.create())
                .addCallAdapterFactory(new ErrorCallAdapter.MyCallAdapterFactory())
                .client(httpClient)
                .build();
        return retrofit;

API接口:

 @GET("api/getTheResults")
 ErrorCallAdapter.MyCall<GeneralResponse<SomeEntity> getGenericMethod();

ErrorCallAdapter的一部分:

@Override
        public void enqueue(final MyCallback<Object> callback) {
            call.enqueue(new Callback<GeneralResponse<T>>() {
                @Override
                public void onResponse(final Call<GeneralResponse<T>> call, final Response<GeneralResponse<T>> response) {
                    final int code = response.code();
                    mainHandler.post(new Runnable() {
                        @Override
                        public void run() {
                            if (response.isSuccessful()) {
                                if (response.body().getStatus() == 1) {
                                    callback.onResult(response.body().getResponse());
                                } else
                                    callback.onError(response.body().getMError());
                            } else
                                callback.onError(new MError(code,
                                        response.message() != null ? response.message() : "onResponse error"));
                        }
                    });
                }

                @Override
                public void onFailure(Call<GeneralResponse<T>> call, Throwable t) {
                    if (t != null)
                        callback.onError(new MError(501,
                                t.getMessage() != null ? t.getMessage() : "unexpected error"));
                    else
                        callback.onError(new MError(501,
                                "unexpected error"));
                }
            });

        }

获取数据的一部分:

public void loadUserSetupData() {
        ErrorCallAdapter.MyCall<GeneralResponse<Data>, Data> DataCall = apiManager.getData();
        setupDataMyCall.enqueue(new ErrorHandlingCallAdapter.MyCallback<Data>() {
            @Override
            public void onResult(Data data) {
                endProgressDialog();

                apiResult.onSuccess(data);
            }

            @Override
            public void onError(MError mError) {
                endProgressDialog();
                apiResult.onError(mError.getErrorMessage(mContext));
            }
        });
    }

我试图获取的数据是JSON格式的,如下所示:

{
    "Status": 1,
    "Error": null,
    "ResponseList": [
        {
            "ErCode": 0,
            "Masseg": null,
            "DType": "OnceData",
            "Contents": {
                "VList": [{
                    "name":"name"
                    "name":"name"
                    "name":"name"
                  }],
                "WList": [{
                    "name":"name"
                    "name":"name"
                    "name":"name"
                  }, {
                    "name":"name"
                    "name":"name"
                    "name":"name"
                  }],
                "UList": [{
                    "name":"name"
                    "dd":"ddd" "DobledataType"
                    "object":"name"  "object data type"
                  }, {
                    "name":"name"
                    "int":"1"
                    "code":"15.00" "float data type
                  }],

            }
        }
    ]
}

在上面,我将“name”称为实体对象(UList、VList、WList中的每一个都是仅用于说明的对象)

我的问题是:我如何使改造适用于任何类型的数据,它将获取对象,不管它是什么类型,意味着我不知道“内容”列表是否有特定类型的对象,我想让它工作在我可以接收任何类型的数据,不管它是什么类型,而不知道对象,我们可以指定msg,DType(在前面的例子中知道DType=data将执行一些操作),但我们不知道响应对象的类型(字符串、对象、整数的arraylist或一个字符串) 我们如何在安卓系统的改造中做到这一点


共 (1) 个答案

  1. # 1 楼答案

    如果你根本不知道“Contents”字段的内容是什么,你可以直接在你的模型中将它设置为一个JSONObject,但是每次你想从Contents字段中检索一些东西时,你都需要做一些工作

    但是,如果您知道它可以具有什么类型,例如,您肯定知道它将是字符串数组、字符串或int,那么您就有了使用自定义GSON deserializer的解决方案

    首先,您必须更改模型/Pojo以处理每种类型,例如:

    abstract class Model {
        // put here all the fields you know the type is stable
    }
    
    // for when content is a list
    public class ListModel extends Model {
        @SerializedName("Contents")
        List<String> content;
    }
    
    // for when content is a String
    public class StringModel extends Model {
        @SerializedName("Contents")
        String content;
    }
    
    // add every other derived class you need for the other types that the content field can have
    

    现在,您可以创建一个反序列化程序,它将返回正确的模型对象:

    public class ModelDeserializer implements JsonDeserializer<Model> {
        @Override
        public Model deserialize(JsonElement json, Type typeOfT, 
                                 JsonDeserializationContext context) 
                                 throws JsonParseException {
            JsonObject jsonObject = json.getAsJsonObject();
    
            // get the "contents" field
            JsonElement contents = jsonObject.get("Contents");
            if (contents != null) {
                if (contents.isJsonArray()) { // if this is a list, parse as ListModel
                    return context.deserialize(jsonObject, 
                        ListModel.class);
                }
                if (contents.isJsonPrimitive()) { // json primitives are number, string, bool, character
                    if (contents.getAsJsonPrimitive().isString() {
                        return context.deserialize(jsonObject, StringModel.class);
                    }
                }
                // do the same for every other type you might have
            }
            return null;
        }
    }
    

    最后,您必须告诉Renformation和Gson使用该反序列化程序:

    Gson gson = new GsonBuilder()
             .registerTypeAdapter(Model.class, new ModelDeserializer())
             .create();
    
    // just add the new gson object to your converterfactory
    retrofit = new Retrofit.Builder()
                .baseUrl(url)
                .addConverterFactory(GsonConverterFactory.create(gson))
                .addCallAdapterFactory(new ErrorCallAdapter.MyCallAdapterFactory())
                .client(httpClient)
                .build();
        return retrofit;
    

    它应该会起作用