如何使用 JSONarray 中的动态键编写 Pojo

How to write a Pojo using a dynamic key inside JSONarray

我什至不知道这是否是一个有效问题,但我很难将 API 结果转换为 POJO,因为某些键是动态的。

{
"data": [{
        "something_edit": true
    },
    {
        "test_null": false
    }
],
"success": true

}

如您所见,数据中的键是动态的。我尝试使用 jsonschema2pojo 或其他转换器,但它声明了一个命名变量,这不是一个好结果。顺便说一句,我正在使用改造和 GSON 库

编辑:

这是流程,所以密钥是我在 API 上问的那些。例如,我问了 something_edit1、something_edit2 和 something_edit3。数据结果将是。

{

"data": [{
        "something_edit1": true
    }, {
        "something_edit2": false
    },
    {
        "something_edit3": false
    }
],

"success": true
}

您可以使用 Json ObjectGenerics 来满足您的条件。

Using Json Object you can check, if key is exist in your json.

if(yourJsonObject.hasOwnProperty('key_name')){
   // do your work here
}

Using Generic you have to check, if your Pojo have instance of the Pojo.

if(YourMainPOJO instanceOf YourChildPojo){
   // do your work here
}

尝试仅查看此 link.

中的 Generic 部分

很难确定,或者您必须在 POJO 中声明所有可能的字段,或者编写自己的 json 解析器扩展 Gson 解析器,或者使用可以转换为 json 数组的 JsonElement ,对象和基元,基于该结果,您可以转换回某些特定的 pojo。

   /**
 * this will convert the whole json into map which you can use to determine the json elements
 *
 * @param json
 */
private void getModelFromJson(JsonObject json) {
    Gson gson = new Gson();
    Map<String, JsonElement> jsonElementMap = gson.fromJson(json.toString(), new TypeToken<Map<String, JsonElement>>() {
    }.getType());
    for (Map.Entry<String, JsonElement> jsonElementEntry : jsonElementMap.entrySet()) {
        if (jsonElementEntry.getValue().isJsonPrimitive()) {
            //json primitives are data types, do something
            //get json boolean
            //you can here also check if json element has some json object or json array or primitives based on that
            //you can convert this to something else after comparison
            if (true) {
                InterestModelResponse response = gson.fromJson(jsonElementEntry.getValue().getAsJsonObject().toString(), InterestModelResponse.class);
                //use your dynamic converted model
            }
        } else {
            //do something else
        }
    }

}

2 年前我们做了一个项目,在这个项目中,我们必须在同一数组中处理具有不同类型对象的通知数据,我们在使用改造时处理该数据

这是我们的改造Creatorclass

class Creator {
    public static FullTeamService newFullTeamService() {
        final HttpLoggingInterceptor interceptor = new HttpLoggingInterceptor();
        interceptor.setLevel(HttpLoggingInterceptor.Level.BODY);
        final OkHttpClient client = new OkHttpClient.Builder()
                .addInterceptor(interceptor)
                .build();

        final Retrofit retrofit = new Retrofit.Builder()
                .baseUrl(FullTeamService.HOST)
                .client(client)
                .addConverterFactory(GsonConverterFactory.create(GsonUtils.get()))
                .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
                .build();
        return retrofit.create(FullTeamService.class);
    }
}

GsonUtils.java是:

public class GsonUtils {
    private static final Gson sGson = new GsonBuilder()
        .setDateFormat("yyyy-MM-dd'T'HH:mm:ss")
        .registerTypeAdapter(NotificationObject.class, new NotificationDeserializer())
        .create();

   private GsonUtils() {}

   public static Gson get() {
    return sGson;
   }
}

NotificationObject 类似于:

public class NotificationObject {

@SerializedName("ID")
@Expose
private long ID;

@SerializedName("type")
@Expose
private Type type;

@SerializedName("DataObject")
@Expose
private NotificationDataObject dataObject;

public void setDataObject(NotificationDataObject newsFields) {
    dataObject = newsFields;
}

@SuppressWarnings("unchecked")
public <T> T getDataObject() {
    return (T) dataObject;
}
public enum Type {
    @SerializedName("0")
    CHAT_MESSAGE,
    @SerializedName("10")
    GAME_APPLICATION,
    @SerializedName("20")
    GAME_APPLICATION_RESPONSE,
    @SerializedName("30")
    GAME_INVITE....
}
}

NotificationDataObject 作为新 class 就像:

public class NotificationDataObject {}

最后 NotificationDeserializer 就像:

public class NotificationDeserializer implements JsonDeserializer<NotificationObject> {
@Override
public NotificationObject deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
    final JsonObject itemBean = json.getAsJsonObject();
    final NotificationObject object = GsonUtils.getSimpleGson().fromJson(itemBean, NotificationObject.class);
    switch (object.getType()) {
        case CHAT_MESSAGE:
            break;
        case GAME_APPLICATION:
            object.setDataObject(GsonUtils.get().fromJson(itemBean.get("DataObject").getAsJsonObject(),
                    GameApplicationNotification.class));
            break;
        case GAME_APPLICATION_RESPONSE:
            object.setDataObject(GsonUtils.get().fromJson(itemBean.get("DataObject").getAsJsonObject(),
                    GameApplicationResponseNotification.class));
            break;
        case GAME_INVITE:
            object.setDataObject(GsonUtils.get().fromJson(itemBean.get("DataObject").getAsJsonObject(),
                    GameInviteNotification.class));
            break;
}
    return object;
}
}

编码愉快...!

如有疑问,我们将不胜感激...