gpt4 book ai didi

java - 无法使用 Gson 将对象(使用 Room DB)序列化为 json 字符串

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:20:59 24 4
gpt4 key购买 nike

我有一个类 Item(见下文),我在其中使用了一些 Room db 注释。它还有一个名为 ItemInfo 的嵌套类。这两个类都有一个空的构造函数。

问题是,当我尝试序列化 Item 类的对象时,应用程序崩溃并出现以下错误:

E/AndroidRuntime: FATAL EXCEPTION: main
Process: com.android.carrymates, PID: 18526
java.lang.SecurityException: Can not make a java.lang.reflect.Method constructor accessible
at java.lang.reflect.AccessibleObject.setAccessible0(AccessibleObject.java:133)
at java.lang.reflect.AccessibleObject.setAccessible(AccessibleObject.java:119)
at com.google.gson.internal.reflect.PreJava9ReflectionAccessor.makeAccessible(PreJava9ReflectionAccessor.java:31)
at com.google.gson.internal.ConstructorConstructor.newDefaultConstructor(ConstructorConstructor.java:103)
at com.google.gson.internal.ConstructorConstructor.get(ConstructorConstructor.java:85)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:101)
at com.google.gson.Gson.getAdapter(Gson.java:458)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:117)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:166)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
at com.google.gson.Gson.getAdapter(Gson.java:458)
at com.google.gson.internal.bind.ArrayTypeAdapter$1.create(ArrayTypeAdapter.java:48)
at com.google.gson.Gson.getAdapter(Gson.java:458)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:117)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:166)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
at com.google.gson.Gson.getAdapter(Gson.java:458)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:117)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:166)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
at com.google.gson.Gson.getAdapter(Gson.java:458)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:117)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:166)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
at com.google.gson.Gson.getAdapter(Gson.java:458)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.createBoundField(ReflectiveTypeAdapterFactory.java:117)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.getBoundFields(ReflectiveTypeAdapterFactory.java:166)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory.create(ReflectiveTypeAdapterFactory.java:102)
at com.google.gson.Gson.getAdapter(Gson.java:458)
at com.google.gson.Gson.toJson(Gson.java:696)
at com.google.gson.Gson.toJson(Gson.java:683)
at com.google.gson.Gson.toJson(Gson.java:638)
at com.google.gson.Gson.toJson(Gson.java:618)
... more log (irrelevant to question asked)

项目.java

@Entity(tableName = "items", indices = {@Index(value = {"id"}, unique = true), @Index(value = {"owner", "type"})})
public class Item {

@PrimaryKey
@NonNull
String id="";

//...rest fields are int, boolean and String only

@Embedded
ItemInfo itemInfo; // see ItemInfo


public Item() {

}


// ...getters and setters

@IgnoreExtraProperties
public static class ItemInfo {

//...fields are int, boolean and String only

public ItemInfo() {

}

//...getters and setters
}
}

我的猜测是 Room DB 注释至少添加了一个 Gson 无法序列化的 java.lang.reflect.Method 类型的对象。

下面是我用来将 Item 对象序列化为 json 字符串的代码,其中 item 是类 Item 的对象,具有 String 类型字段的非空值和 ItemInfo

Gson gson = new Gson();
String result = gson.toJson(item); // crash begins from here

我该如何解决这个问题?我希望至少有一个变通解决方案。

最佳答案

免责声明:

我不知道 RoomDB@Entity 类做了什么(尽管看起来 RoomDB 使用子类而不是您编写的类)。

我还在 JVM 上运行测试

但我可以建议您使用 @Expose :

public class GsonTest {

private static class SampleModel {
@Expose
private int i;

private Method method;

@Expose
private Nested nested = new Nested();
}

private static class Nested {
@Expose
private String a = "my string";
}

@Test
public void failsWithMethodField() throws Exception {
assertThrows(Exception.class, () -> {
SampleModel sampleModel = new SampleModel();
sampleModel.i = 10;
sampleModel.method = Object.class.getDeclaredMethod("equals", Object.class);
Gson gson = new Gson();
gson.toJson(sampleModel);
});
}

@Test
public void withExposedDoesNotFail() {
assertDoesNotThrow(() -> {
SampleModel sampleModel = new SampleModel();
sampleModel.method = Object.class.getDeclaredMethod("equals", Object.class);
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
String json = gson.toJson(sampleModel);
System.out.println(json); // {"i":0,"nested":{"a":"my string"}}
});
}
}

关键部分是使用excludeFieldsWithoutExposeAnnotation 选项配置Gson:

Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();

然后用@Expose注解标记所有在序列化和反序列化时应该使用的字段。

关于java - 无法使用 Gson 将对象(使用 Room DB)序列化为 json 字符串,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52191827/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com