GSON反序列化问题

3
我正在使用GSON库时遇到反序列化问题。
以下是我尝试反序列化的JSON代码。
{"response": {
  "@service": "CreateUser",
  "@response-code": "100",
  "@timestamp": "2010-11-27T15:52:43-08:00",
  "@version": "1.0",
  "error-message": "",
  "responseData": {
    "user-guid": "023804207971199"
  }
}}

我创建了以下类:

public class GsonContainer {

        private GsonResponse mResponse;

        public GsonContainer() { }

        //get & set methods

}

public class GsonResponse {

    private String mService;
    private String mResponseCode;
    private String mTimeStamp;
    private String mVersion;
    private String mErrorMessage;

    private GsonResponseCreateUser mResponseData;

    public GsonResponse(){

    }

    //gets and sets method
}

public class GsonResponseCreateUser {

    private String mUserGuid;

    public GsonResponseCreateUser(){

    }

    //get and set methods
}

调用GSON库后数据为空。这些类有什么问题?谢谢您提前的帮助...我想这应该是一些微不足道的问题...
2个回答

11

@user523392 说:

成员变量必须与 JSON 响应中给出的完全匹配

事实并非如此。

有几种选项可以指定 Java 字段名称映射到 JSON 元素名称的方式。

对于上面原始问题中的情况,一个可行的解决方案是使用 @SerializedName 注释 Java 类成员,以明确声明它映射到的 JSON 元素名称。

// output: [MyObject: element=value1, elementTwo=value2]

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.annotations.SerializedName;

public class Foo
{
  static String jsonInput =
      "{" +
          "\"element\":\"value1\"," +
          "\"@element-two\":\"value2\"" +
      "}";

  public static void main(String[] args)
  {
    GsonBuilder gsonBuilder = new GsonBuilder();
    Gson gson = gsonBuilder.create();
    MyObject object = gson.fromJson(jsonInput, MyObject.class);
    System.out.println(object);
  }
}

class MyObject
{
  String element;

  @SerializedName("@element-two")
  String elementTwo;

  @Override
  public String toString()
  {
    return String.format(
        "[MyObject: element=%s, elementTwo=%s]",
        element, elementTwo);
  }
}

另一种方法是创建一个自定义的FieldNamingStrategy来指定如何将Java成员名称转换为JSON元素名称。此示例将应用相同的名称映射到所有Java成员名称。这种方法不适用于上面的原始示例,因为并非所有JSON元素名称都遵循相同的命名模式--它们并不都以“@”开头,有些使用驼峰命名法而不是使用“-”分隔名称部分。此FieldNamingStrategy的实例将在构建Gson实例时使用(gsonBuilder.setFieldNamingStrategy(new MyFieldNamingStrategy());)。
class MyFieldNamingStrategy implements FieldNamingStrategy
{
  // Translates the field name into its JSON field name representation.
  @Override
  public String translateName(Field field)
  {
    String name = field.getName();
    StringBuilder translation = new StringBuilder();
    translation.append('@');
    for (int i = 0, length = name.length(); i < length; i++)
    {
      char c = name.charAt(i);
      if (Character.isUpperCase(c))
      {
        translation.append('-');
        c = Character.toLowerCase(c);
      }
      translation.append(c);
    }
    return translation.toString();
  }
}

另一种处理Java字段名与JSON元素名映射的方法是在构建Gson实例时指定FieldNamingPolicy,例如gsonBuilder.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_DASHES)。然而,这种方法也无法解决原始示例中的问题,因为它将相同的命名映射策略应用于所有情况。

0
上面的JSON响应由于特殊字符@和-而无法被GSON反序列化。 GSON基于反射,成员变量必须与JSON响应中给出的完全匹配。

如果我想反序列化对象,但名称与JSON响应键名称不匹配,我该怎么办?是否有DeSerialize注释可用?因为Serialize注释仅在进行序列化时起作用,但在进行反序列化时会怎样呢? - user622578

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接