使用Jackson

时间:2016-10-15 20:35:49

标签: java json recursion jackson infinite

我有这个类用于存储工具的首选项。该类使用toString()将自身转换为JSON。当我将对象转换为JSON时,我收到此无限递归错误,我无法弄清楚原因。我没有任何循环引用,所以它让我有点困惑。任何帮助将不胜感激。

这是我的班级结构:

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:无限递归(StackOverflowError)(通过引用链:java.awt.Point [" location"] - > java.awt.Point [&#34 ;位置"] - > java.awt.Point中["位置"] - > java.awt.Point中["位置"] ...)       在com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:518)       在com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:117)       at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:464)       在com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:504)       在com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:117)       at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:464)       在com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:504)       在com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:117)       at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:464)       在com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:504)       在com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:117)

2 个答案:

答案 0 :(得分:3)

您遇到的问题是由于您的对象正在嵌入的Point类。

要解决此问题,您可以指示Jackson停留在第一级深度,并且要实施此解决方案,您可以按照以下步骤操作:

1)首先,你必须运行杰克逊的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;

杰克逊将停在第一级,结果将是:

{
  "dialogLocation" : {
    "x" : 2.0,
    "y" : 3.0
  }
}

有关进一步的文档,您可以看到:

Limit Jackson output to only one level

Enable default view inclusion on Jackson 2.x ObjectMapper

我已经测试了解决方案,只要您使用2.x版本的Jackson,它就能正常运行。使用1.x,我无法让它运行起来。

答案 1 :(得分:-2)

或试试这个

ObjectMapper mapper = new ObjectMapper();
String perttyStr = mapper.writerWithDefaultPrettyPrinter().writeValueAsString(object);
相关问题