【问题标题】:Jackson ObjectMapper gives error with recursive datatypeJackson ObjectMapper 给出递归数据类型错误
【发布时间】:2017-01-10 20:10:00
【问题描述】:

我有 pojo DTNodo,它有一个递归属性 List<DTNodo>。 当我尝试使用 jackson 生成 json 架构时,我得到一个 java.lang.StackOverflowError 异常。

如果我删除 List 属性,它可以正常工作,所以问题出在递归上。

有没有办法告诉 ObjectMapper 这个递归以便正确处理它?有没有其他方法可以生成这个 json 架构?

DTNodo 类

public class DTNodo implements Serializable {

    private static final long serialVersionUID = 1L;

    private Integer idNodo;
    private String codigo;
    private String descripcion;
    private String detalle;
    private Integer orden;

    private List<DTNodo> hijos;

    public Integer getIdNodo() {
        return idNodo;
    }

    public void setIdNodo(Integer idNodo) {
        this.idNodo = idNodo;
    }

    public String getCodigo() {
        return codigo;
    }

    public void setCodigo(String codigo) {
        this.codigo = codigo;
    }

    public String getDescripcion() {
        return descripcion;
    }

    public void setDescripcion(String descripcion) {
        this.descripcion = descripcion;
    }

    public String getDetalle() {
        return detalle;
    }

    public void setDetalle(String detalle) {
        this.detalle = detalle;
    }

    public Integer getOrden() {
        return orden;
    }

    public void setOrden(Integer orden) {
        this.orden = orden;
    }

    public List<DTNodo> getHijos() {
        return hijos;
    }

    public void setHijos(List<DTNodo> hijos) {
        this.hijos = hijos;
    }

}

我用来生成 jsonschema 的代码

public static String getJsonSchema(Class<?> clazz) {
    ObjectMapper mapper = new ObjectMapper();
    JsonSchema schema;
    try {
        schema = mapper.generateJsonSchema(clazz);

        return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(schema);

    } catch (IOException e) {
        return "Error al generar JsonSchema: " + e.getMessage();
    }
}

【问题讨论】:

  • 杰克逊的哪个版本?
  • 现在我使用的是 com.fasterxml.jackson.core 2.8.5,之前我使用的是 org.codehaus.jackson 1.9.13。两者都给了我同样的错误。

标签: java json jackson jsonschema


【解决方案1】:

ObjectMapper.generateJsonSchema 已弃用。您需要改用the new JSON schema module

com.fasterxml.jackson.module:jackson-module-jsonSchema:${jacksonVersion} 添加到您的项目并生成如下架构:

ObjectMapper mapper = new ObjectMapper();
JsonSchemaGenerator schemaGen = new JsonSchemaGenerator(mapper);
JsonSchema schema = schemaGen.generateSchema(clazz);
mapper.writerWithDefaultPrettyPrinter().writeValueAsString(schema);

确保从正确的包中导入现代 JsonSchema:

import com.fasterxml.jackson.module.jsonSchema.JsonSchema;

【讨论】:

  • 完美运行。谢谢!
【解决方案2】:

没有简单的出路。 您应该尽量避免一次性序列化导致 POJO 中引用循环的属性。

您可以实现类似以下示例(将对象序列化为引用),但您必须确保客户端应用程序能够反序列化它:

{
   "id": "1",
   "name": "John",
   "friends": [
      {
          "id": "2",
          "name": "Jared",
          "friends": [
                    {
                        "$ref": "1"
                    }
                ]
      }
}

我要做的是序列化父对象,而没有导致循环的属性 (@JsonIgnore)。然后序列化其余部分并使客户端应用程序重组对象。

您可以使用@JsonManagedReference@JsonBackReference

更多信息:http://www.baeldung.com/jackson-bidirectional-relationships-and-infinite-recursion

【讨论】:

  • 虽然这对于使用循环引用序列化对象是一个很好的建议,但 OP 询问的是 模式生成 期间的无限递归,这是一个不同的问题。
猜你喜欢
  • 2021-11-14
  • 2016-12-29
  • 1970-01-01
  • 2013-06-18
  • 1970-01-01
  • 2015-02-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多