问题描述
我有一个循环引用的结构。
为了调试目的,我想转储它。基本上就是任何格式,但我选择了JSON。
因为它可以是任何类,所以我选择了不需要JAXB注释的GSON。
但是GSON命中循环引用并递归,直到 StackOverflowError
。
我该如何将GSON限制为
-
忽略某些类成员?
不符合@XmlTransient
和@JsonIgnore
。 -
忽略某些对象图路径?例如。我可以指示GSON不要序列化
release.customFields.product
。 -
最高2级?
相关:
简单地设置字段transient(如 private transient int field = 4;
)。 GSON了解这一点。
编辑
无需内置注释; Gson让你插入你自己的战略,排除领域和类。它们不能基于路径或嵌套级别,但注释和名称很好。
如果我想跳过类my.model.Person上名为lastName的字段,我可以写下如下的排除策略:
class MyExclusionStrategy实现了ExclusionStrategy {
public boolean shouldSkipField(FieldAttributes fa){
String className = fa。 。getDeclaringClass()的getName();
String fieldName = fa.getName();
返回
className.equals(my.model.Person)
&& fieldName.equals( 姓氏);
$ b @Override
public boolean shouldSkipClass(Class<?> type){
//永远不会跳过任何类
return false;
我也可以创建自己的注释:
@Retention(RetentionPolicy.RUNTIME)
public @interface GsonRepellent {
}
然后将 shouldSkipField
方法重写为:
public boolean shouldSkipField(FieldAttributes fa){
return fa.getAnnotation(GsonRepellent.class)!= null;
}
这可以让我做这样的事情:
public class Person {
@GsonRepellent
private String lastName =Troscianko;
// ...
要使用自定义ExclusionStrategy,请构建Gson使用构建器的对象:
$ pre $ g $ gson new GsonBuilder
setsettingStrategies(new MyOwnExclusionStrategy())
.create();
I have a structure with circular references.And for debug purposes, I want to dump it. Basically as any format, but I chose JSON.
Since it can be any class, I chose GSON which doesn't needs JAXB annotations.
But GSON hits the circular references and recurses until StackOverflowError
.
How can I limit GSON to
ignore certain class members?Both
@XmlTransient
and@JsonIgnore
are not obeyed.ignore certain object graph paths? E.g. I could instruct GSON not to serialize
release.customFields.product
.go to the depth of at most 2 levels?
Related: Gson.toJson gives StackOverFlowError, how to get proper json in this case? (public static class)
Simply make the fields transient (as in private transient int field = 4;
). GSON understands that.
Edit
No need for a built-in annotation; Gson lets you plug in your own strategies for excluding fields and classes. They cannot be based on a path or nesting level, but annotations and names are fine.
If I wanted to skip fields that are named "lastName" on class "my.model.Person", I could write an exclusion strategy like this:
class MyExclusionStrategy implements ExclusionStrategy {
public boolean shouldSkipField(FieldAttributes fa) {
String className = fa.getDeclaringClass().getName();
String fieldName = fa.getName();
return
className.equals("my.model.Person")
&& fieldName.equals("lastName");
}
@Override
public boolean shouldSkipClass(Class<?> type) {
// never skips any class
return false;
}
}
I could also make my own annotation:
@Retention(RetentionPolicy.RUNTIME)
public @interface GsonRepellent {
}
And rewrite the shouldSkipField
method as:
public boolean shouldSkipField(FieldAttributes fa) {
return fa.getAnnotation(GsonRepellent.class) != null;
}
This would enable me to do things like:
public class Person {
@GsonRepellent
private String lastName = "Troscianko";
// ...
To use a custom ExclusionStrategy, build Gson object using the builder:
Gson g = new GsonBuilder()
.setExclusionStrategies(new MyOwnExclusionStrategy())
.create();
这篇关于GSON:如何在保留循环引用的同时防止StackOverflowError?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!