【问题标题】:gson array deserialization with extra variables带有额外变量的 gson 数组反序列化
【发布时间】:2017-11-04 10:26:34
【问题描述】:

我不确定这是否可能重复,但我找不到类似的问题。

目前,我正在尝试从我公司使用的 API 中检索一个数组。 由于我从 API 中检索了所有这些数据,因此我还会收到一条状态消息,其中包含字符串成功或字符串错误。 我正在使用 Gson 和 Retrofit 来检索和反序列化 JSON 数据。

这适用于每个对象,但现在我需要创建一个也是数组的对象。

从 API 检索到的 json 输出。

{
   "0":{
      "first_name":"Menno",
      "avatar":"[avatar here]",
      "updated_at":"2017-04-08 11:17:35",
      "id":"[id here]"
   },
   "1":{
      "first_name":"Team",
      "avatar":"[avatar here]",
      "updated_at":"2017-11-01 11:00:18",
      "id":"[id here]"
   },
   "success":"retrieve_common_connections_success"
}

如您所见,json 以索引数组开始并以成功消息结束。

用于反序列化 JSON 的类。

public class GetCommonConnections extends ArrayList<Connection> {
    public String getSuccess() {
        return success;
    }

    public void setSuccess(String success) {
        this.success = success;
    }

    public String getError() {
        return error;
    }

    public void setError(String error) {
        this.error = error;
    }

    @SerializedName("success")
    private String success = "";
    @SerializedName("error")
    private String error = "";

}

我也收到错误:D/Error: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 2 path $

这意味着 gson 期望以数组开头,但它以对象开头。 我对它的工作原理有点迷茫,想知道你们中是否有人有解决方案。

编辑

连接类。

public class Connection {
    private String first_name;
    private String avatar;
    private String updated_at;
    private int id;

    public String getFirst_name() {
        return first_name;
    }

    public void setFirst_name(String first_name) {
        this.first_name = first_name;
    }

    public String getAvatar() {
        return avatar;
    }

    public void setAvatar(String avatar) {
        this.avatar = avatar;
    }

    public String getUpdated_at() {
        return updated_at;
    }

    public void setUpdated_at(String updated_at) {
        this.updated_at = updated_at;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }
}

还有使用的接口。

public interface IGetCommonConnections {
    @POST(PostInterfaceMain.POST_URL)
    Call<CommonConnections> getCommonConnections(
            @Body PostConnections body
            );
}

调用API的方法

public static void getCommonConnections(int resourceID, final CustomCallbackHandler callback)
    {
        PostConnections body = new PostConnections();
        body.setResourceID(resourceID);
        body.setAction("resource_get_common_connections");

        IGetCommonConnections taskService = ServiceGenerator.createService(IGetCommonConnections.class);
        Call<CommonConnections> call = taskService.getCommonConnections(body);
        call.enqueue(new Callback<CommonConnections>() {
            @Override
            public void onResponse(Call<CommonConnections> call, Response<CommonConnections> response) {
                if (response.isSuccessful()) {
                    Log.d(TAG, "CommonConnections succesfully retrieved!");
                    callback.setArg(response.body());
                    callback.run();
                } else {
                    // error response, no access to resource?
                }
            }

            @Override
            public void onFailure(Call<CommonConnections> call, Throwable t) {
                // something went completely south (like no internet connection)
                Log.d("Error", t.getMessage());
            }
        });
    }

【问题讨论】:

  • 你想把 obj 转成 json 吗?
  • 你必须使用MapList只有在你有[而不是{时才有效
  • 你能添加你的改造方法来调用API吗?和连接类到
  • 会做@FarshidABZ,Saurabh 你到底是什么意思? Amit 我想将 json 转换为 Java 对象。
  • 尝试调用:Call> getCommonConnections(...);

标签: android arrays json arraylist gson


【解决方案1】:

按原样使用 Connection.java

GetCommonConnections.java

public class GetCommonConnections implements JsonDeserializer<GetCommonConnections>, 
JsonSerializer<GetCommonConnections> {

    public TreeMap<Long, Connection> connectionTreeMap;

    public String success;

    public String error;

    @Override
    public GetCommonConnections deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {

        Gson gson = new Gson();
        GetCommonConnections getCommonConnections = gson.fromJson(json, GetCommonConnections.class);
        getCommonConnections.connectionTreeMap = new TreeMap<>();

        JsonObject jsonObject = json.getAsJsonObject();
        Set<String> keySet = jsonObject.keySet();
        Iterator<String> keyIterator = keySet.iterator();

        while (keyIterator.hasNext()) {

            String key = keyIterator.next();

            if (TextUtils.isDigitsOnly(key)) {

                getCommonConnections.connectionTreeMap.put(Long.valueOf(key),
                        gson.fromJson(jsonObject.get(key), Connection.class));
            }
        }

        return getCommonConnections;
    }

    @Override
    public JsonElement serialize(GetCommonConnections src, Type typeOfSrc, JsonSerializationContext context) {

        Gson gson = new Gson();
        JsonObject jsonObject = new JsonObject();

        Set<Long> longSet = src.connectionTreeMap.keySet();
        Iterator<Long> longIterator = longSet.iterator();

        while (longIterator.hasNext()) {

            Long key = longIterator.next();

            jsonObject.add(String.valueOf(key),
                    gson.toJsonTree(src.connectionTreeMap.get(key)));
        }

        jsonObject.addProperty("success", src.success);
        jsonObject.addProperty("error", src.error);

        return jsonObject;
    }
}

CustomGsonConverterFactory

public GsonConverterFactory createCustomGsonConverterFactory() {

        GsonBuilder gsonBuilder = new GsonBuilder();

        gsonBuilder.registerTypeAdapter(GetCommonConnections.class,
                new GetCommonConnections());

        Gson gson = gsonBuilder.create();

        return GsonConverterFactory.create(gson);
    }

如下构建改造 -

public Retrofit buildRetrofit() {

    return new Retrofit.Builder()
            .baseUrl("your base URL")
            .addConverterFactory(createCustomGsonConverterFactory())
            .build();
}

测试 GetCommonConnections JsonDeserializer 和 JsonSerializer 是否有效的代码 -

public class MainActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        String jsonResponseString = "{\n" +
                "   \"0\":{\n" +
                "      \"first_name\":\"Menno\",\n" +
                "      \"avatar\":\"[avatar here]\",\n" +
                "      \"updated_at\":\"2017-04-08 11:17:35\",\n" +
                "      \"id\":101\n" +
                "   },\n" +
                "   \"1\":{\n" +
                "      \"first_name\":\"Team\",\n" +
                "      \"avatar\":\"[avatar here]\",\n" +
                "      \"updated_at\":\"2017-11-01 11:00:18\",\n" +
                "      \"id\":102\n" +
                "   },\n" +
                "   \"success\":\"retrieve_common_connections_success\"\n" +
                "}";

        GsonBuilder gsonBuilder = new GsonBuilder();
        gsonBuilder.registerTypeAdapter(GetCommonConnections.class,
                new GetCommonConnections());
        Gson gson = gsonBuilder.create();

        GetCommonConnections getCommonConnections = gson.fromJson(jsonResponseString, GetCommonConnections.class);

        Log.d("MainActivity", "-> " + gson.toJson(getCommonConnections));
    }
}

还有你这个电话无处不在 -

Call<GetCommonConnections>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-24
    • 2011-03-28
    • 1970-01-01
    相关资源
    最近更新 更多