![](/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.