简体   繁体   English

Gson解析为包含JsonArray的Object

[英]Gson parsing into Object that contains a JsonArray

See solution at the end. 请参阅最后的解决方案。

original question 原始问题

I have the following object in my code that I'm trying to deserialize with Gson. 我的代码中有以下对象,试图与Gson反序列化。

public class Foo {
    public Map<String, JSONArray> bar = new HashMap<>();
    public ... other stuff
}

I've also tried with: 我也尝试过:

public class Foo {
    public Map<String, String> bar = new HashMap<>();
    public ... other stuff
}

The reason here is because the Map will be feed into sub-modules that could be any data type. 这里的原因是因为Map将被馈送到可以是任何数据类型的子模块中。 Internally each module knows how to parse its own data. 内部每个模块都知道如何解析自己的数据。

on the JsonArray version I get this error: JsonArray版本上,我收到此错误:

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: 
   Expected BEGIN_OBJECT but was BEGIN_ARRAY at line 3 column 18 path $.trigger.

and in the String version I get this error: String版本中,我得到此错误:

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException:
   Expected a string but was BEGIN_ARRAY at line 3 column 18 path $.trigger.

My question is: 我的问题是:

Can I parse this without the need of a custom deserializer? 是否可以在不需要自定义反序列化器的情况下进行解析? How? 怎么样?

Edit: below is the relevant bits of code: 编辑:下面是相关的代码位:

// Gson is singleton provided by Dagger2
Gson gson = new GsonBuilder().create();

// retrofit is also singleton provided by dagger
Retrofit restAdapter = new Retrofit.Builder()
    .baseUrl(baseUrl)
    .client(buildOkHttpClient(context))
    .addConverterFactory(ScalarsConverterFactory.create())
    .addConverterFactory(GsonConverterFactory.create(gson))
    .addCallAdapterFactory(RxJava2CallAdapterFactory.create())
    .build();
return restAdapter.create(ApiService.class);

// then the Retrofit API
@GET("our path")
Observable<Foo> getFoo(a couple of values);

I've also tried using a MockTransport that is directly invoking Gson, like following: 我还尝试过使用直接调用Gson的MockTransport,如下所示:

Observable
   .just(fooResponse)
   .delay(101, TimeUnit.MILLISECONDS)
   .map(new Function<String, Foo>() {
      @Override public Interactions apply(String s) throws Exception {
           return gson.fromJson(s, Foo.class);
       }
    });

and below relevant parts of the JSON: 以及JSON相关部分以下:

{
  "bar": {
    "type0": [
      {
        ... object 0
      }
    ],
    "type1": [
      {
        ... object 0
      },
      {
        ... object 1
      }
    ]
  },
  "otherStuff" : {
  }
}

The json is for sure formatted correctly, it's coming from our servers and I've re-checked on jsonlint.com json肯定格式正确,它来自我们的服务器,我已经在jsonlint.com上重新检查过

solution: 解:

it seems that is not possible to do without custom deserializer. 没有自定义反序列化器似乎是不可能的。 So I wrote a serialiser for String, which sounds bad, but I' gladly accept suggestions of a better way of handling it. 所以我为String写了一个序列化器,听起来很糟糕,但是我很乐意接受有关处理它的更好方法的建议。

.registerTypeAdapter(String.class, new JsonDeserializer<String>() {
   @Override
   public String deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        if (json.isJsonPrimitive()) {
            return json.getAsJsonPrimitive().getAsString();
        } else {
            return json.toString();
        }
    }
})

You got this error because you are trying to parse JsonArray but you should parse JsonObject at above mentioned line. 您收到此错误是因为您试图解析JsonArray,但您应该在上述行中解析JsonObject。 I hope it will help!! 希望对您有所帮助!! :) :)

When I tried this it was working fine for me, 当我尝试此操作时,对我来说很好

public class Foo {

    Map<String, List<Map>> bar = new HashMap<String, List<Map>>() ;

}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM