使用 Jackson 将对象转换为 JSON 时的无限递归
Infinite Recursion when convert object to JSON using Jackson
我有这个 class 用来存储工具的首选项。 class 使用 toString() 将自身转换为 JSON。当我将对象转换为 JSON 时出现无限递归错误,我无法弄清楚原因。我没有任何循环引用,所以这让我有点困惑。任何帮助将不胜感激。
这是我的 class 结构:
public class ToolPrefs
{
private boolean isFloating;
private ToolPalettePlacement placement; //this is an enum
private boolean isSelected;
private int dockLocation;
private Point dialogLocation;
private Dimension dialogSize;
public ToolPrefs(){}
public boolean isFloating(){return isFloating; }
public void setFloating(boolean floating){ isFloating = floating; }
public ToolPalettePlacement getPlacement(){ return placement; }
public void setPlacement(ToolPalettePlacement placement){ this.placement = placement;}
public boolean isSelected(){ return isSelected;}
public void setSelected(boolean selected){isSelected = selected;}
public int getDockLocation(){return dockLocation;}
public void setDockLocation(int dockLocation){this.dockLocation = dockLocation; }
public Point getDialogLocation(){return dialogLocation;}
public void setDialogLocation(Point dialogLocation){ this.dialogLocation = dialogLocation;}
public Dimension getDialogSize(){ return dialogSize; }
public void setDialogSize(Dimension dialogSize){this.dialogSize = dialogSize;}
@JsonIgnore @Override
public String toString()
{
String json;
ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
try
{
json = ow.writeValueAsString(this);
}
catch (IOException e)
{
e.printStackTrace();
json = "";
}
return json;
}
}
这是我收到的异常片段:
com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (WhosebugError) (through reference chain: java.awt.Point["location"]->java.awt.Point["location"]->java.awt.Point["location"]->java.awt.Point["location"]...)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:518)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:117)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:464)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:504)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:117)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:464)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:504)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:117)
at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:464)
at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:504)
at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:117)
您遇到的问题是由于您的对象嵌入了 Point
class。
要解决此问题,您可以指示 Jackson 在第一层深度停止,要实施此解决方案,您可以按照以下步骤操作:
1) 首先,你必须是 运行 Jackson 的 2.x 版本,我已经用这个测试了解决方案:
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.3</version>
</dependency>
</dependencies>
2) 当您初始化 ObjectMapper
的新实例时,请执行以下操作:
ObjectWriter ow = new ObjectMapper().configure(DEFAULT_VIEW_INCLUSION, true).writer().withDefaultPrettyPrinter();
3) 在你有 Point
类型的地方,使用注解:
@JsonView(Point.class) Point dialogLocation;
Jackson会停在第一关,结果会是:
{
"dialogLocation" : {
"x" : 2.0,
"y" : 3.0
}
}
更多文档,你可以看这个:
Limit Jackson output to only one level
Enable default view inclusion on Jackson 2.x ObjectMapper
我已经测试了该解决方案,只要您使用 Jackson 的 2.x 版本,它就可以工作。有了 1.x,我还无法做到 运行。
我有这个 class 用来存储工具的首选项。 class 使用 toString() 将自身转换为 JSON。当我将对象转换为 JSON 时出现无限递归错误,我无法弄清楚原因。我没有任何循环引用,所以这让我有点困惑。任何帮助将不胜感激。
这是我的 class 结构:
public class ToolPrefs
{
private boolean isFloating;
private ToolPalettePlacement placement; //this is an enum
private boolean isSelected;
private int dockLocation;
private Point dialogLocation;
private Dimension dialogSize;
public ToolPrefs(){}
public boolean isFloating(){return isFloating; }
public void setFloating(boolean floating){ isFloating = floating; }
public ToolPalettePlacement getPlacement(){ return placement; }
public void setPlacement(ToolPalettePlacement placement){ this.placement = placement;}
public boolean isSelected(){ return isSelected;}
public void setSelected(boolean selected){isSelected = selected;}
public int getDockLocation(){return dockLocation;}
public void setDockLocation(int dockLocation){this.dockLocation = dockLocation; }
public Point getDialogLocation(){return dialogLocation;}
public void setDialogLocation(Point dialogLocation){ this.dialogLocation = dialogLocation;}
public Dimension getDialogSize(){ return dialogSize; }
public void setDialogSize(Dimension dialogSize){this.dialogSize = dialogSize;}
@JsonIgnore @Override
public String toString()
{
String json;
ObjectWriter ow = new ObjectMapper().writer().withDefaultPrettyPrinter();
try
{
json = ow.writeValueAsString(this);
}
catch (IOException e)
{
e.printStackTrace();
json = "";
}
return json;
}
}
这是我收到的异常片段:
com.fasterxml.jackson.databind.JsonMappingException: Infinite recursion (WhosebugError) (through reference chain: java.awt.Point["location"]->java.awt.Point["location"]->java.awt.Point["location"]->java.awt.Point["location"]...) at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:518) at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:117) at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:464) at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:504) at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:117) at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:464) at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:504) at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:117) at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:464) at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:504) at com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:117)
您遇到的问题是由于您的对象嵌入了 Point
class。
要解决此问题,您可以指示 Jackson 在第一层深度停止,要实施此解决方案,您可以按照以下步骤操作:
1) 首先,你必须是 运行 Jackson 的 2.x 版本,我已经用这个测试了解决方案:
<dependencies>
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.3</version>
</dependency>
</dependencies>
2) 当您初始化 ObjectMapper
的新实例时,请执行以下操作:
ObjectWriter ow = new ObjectMapper().configure(DEFAULT_VIEW_INCLUSION, true).writer().withDefaultPrettyPrinter();
3) 在你有 Point
类型的地方,使用注解:
@JsonView(Point.class) Point dialogLocation;
Jackson会停在第一关,结果会是:
{
"dialogLocation" : {
"x" : 2.0,
"y" : 3.0
}
}
更多文档,你可以看这个:
Limit Jackson output to only one level
Enable default view inclusion on Jackson 2.x ObjectMapper
我已经测试了该解决方案,只要您使用 Jackson 的 2.x 版本,它就可以工作。有了 1.x,我还无法做到 运行。