![](/img/trans.png)
[英]Google Gson not deserializing simple object with ArrayList properly
[英]Google Gson issue with deserializing
我有一个 Java 类:
public class Object1 {
private int field1;
private String field2;
private Object2 object2;
private boolean field3;
}
我使用 Gson 将一些 Object1 实例保存为 JSON 字符串:
String jsonString = new Gson().toJson(object1, Object1.class);
然后我向 Object1 类添加了新的 String 字段:
public class Object1 {
private int field1;
private String field2;
private String field4;
private Object2 object2;
private boolean field3;
}
现在我无法使用方法将 json 字符串反序列化为 Object1 实例:
Object1 obj1 = new Gson().fromJson(jsonString, Object1.class);
因为 Gson 抛出异常:
System.err: com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: 需要一个字符串,但在第 1 行第 444 列路径 $.c 处为 BEGIN_OBJECT,位于 com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read( ReflectiveTypeAdapterFactory.java:224) at com.google.gson.Gson.fromJson(Gson.java:887) at com.google.gson.Gson.fromJson(Gson.java:852) at com.google.gson.Gson.fromJson (Gson.java:801) 在 com.google.gson.Gson.fromJson(Gson.java:773)
但为什么? 我有没有一个字段的 JSON 字符串,这不会成为问题。 为什么我不能反序列化它?
Expected a string but was BEGIN_OBJECT
您的json字符串中的field4
不是String类型,请使用Json to POJO生成器来创建适当的对象。
@ 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元素名称都遵循相同的命名模式-它们并非都以'@'开头,并且有些使用驼峰式命名而不是使用'-来分隔名称部分”。 构建Gson实例(gsonBuilder.setFieldNamingStrategy(new MyFieldNamingStrategy()))时,将使用此FieldNamingStrategy的实例。
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);。 但是,这也不适用于原始示例,因为它将相同的名称映射策略应用于所有情况。
事实证明,问题在于混淆。
如果您不使用@SerializedName注释结果,JSON可能像这样:
{“ a”:3436213,“ b”:“某些字符串”,“ c”:{.............},“ d”:true}
我们没有使用它,因为它不是DTO。 在这种情况下,我们仅使用JSON来存储一些不重要的内部数据。 但这对我来说是非常有趣的一课。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.