【问题标题】:Infinite Recursion when convert object to JSON using Jackson使用 Jackson 将对象转换为 JSON 时的无限递归
【发布时间】:2016-10-15 20:35:49
【问题描述】:

我有一个用来存储工具首选项的类。此类使用 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;
   }
}

这是我收到的异常 sn-p:

com.fasterxml.jackson.databind.JsonMappingException:无限递归(StackOverflowError)(通过引用链:java.awt.Point["location"]->java.awt.Point["location"]->java.awt .Point["location"]->java.awt.Point["location"]...) 在 com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:518) 在 com.fasterxml.jackson.databind.ser.BeanSerializer.serialize(BeanSerializer.java:117) 在 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) 在 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) 在 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)

【问题讨论】:

  • 尝试从 toString() 中删除 @JsonIgnore;
  • 它最初不存在,所以我添加它以查看它是否会解决它,但它没有:(
  • 您的问题似乎出在您正在导入的 Point 类中......也许这会有所帮助:impossible-is-development.blogspot.co.uk/2012/08/…

标签: java json recursion jackson infinite


【解决方案1】:

您面临的问题是由于您的 Object 嵌入的 Point 类。

要解决此问题,您可以指示 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,我还无法让它运行。

【讨论】:

  • 谢谢!这似乎也可以。我稍后会试试这个。我最终做的是将 Point 实例包装到“Location”类中,从而解决了无限递归问题。 (去图)
猜你喜欢
  • 2020-05-20
  • 1970-01-01
  • 2013-03-25
  • 2014-05-16
  • 1970-01-01
  • 2015-03-13
  • 2018-11-18
  • 2017-03-26
  • 2016-06-17
相关资源
最近更新 更多