【问题标题】:How to parse JSON in Spring Boot Application automatically using Jackson如何使用 Jackson 自动解析 Spring Boot 应用程序中的 JSON
【发布时间】:2019-07-25 06:41:58
【问题描述】:

我有 json 文件 带有 json 对象 作为里面的属性值:

{
 "name": "name",
 "json": {...}
}

我需要在 RestController自动 获取它,并将其用作 JPA+Hibernate 中的实体。

我的实体是:

UPDATE -> 更多指定实体

@Entity
@Table(name = "collections")
public class Collection {
    @Id
    private String name;

    @Column(name = "cache_limit")
    private int limit;

    @Column(name = "cache_algorithm")
    private String algorithm;

    @Transient
    private JsonNode schema;

    @JsonIgnore
    @Column(name ="json_schema")
    private String jsonSchema;

    public Collection() {
    }

    public String getJsonSchema() {
        return schema.toString();
    }

    public void setJsonSchema(String jsonSchema) {
        ObjectMapper mapper = new ObjectMapper();
        try {
            schema = mapper.readTree(jsonSchema);
        } catch (IOException e) {
            throw new RuntimeException("Parsing error -> String to JsonNode");
        }
    }

   ..setters and getters for name limit algorithm schema..
}

当我使用 entityManager.persist(Collection) 时,我将 json_schema 列为 NULL

我该如何解决?问题可能出在setJsonSchema()

更新

public String getJsonSchema() {
        return jsonSchema;
    }

    public void setJsonSchema(JsonNode schema) {
        this.jsonSchema = schema.toString();
    }

这样的 getter/setter 并不能解决问题

【问题讨论】:

  • “json 字段将为空”是什么意思?你的控制器看起来像Cat getCat(int name){ return cats.getCatByName(name);},它返回JSON 对象,namejson 属性为空?

标签: java json spring jpa jackson


【解决方案1】:

正如this article 中所述,您不必手动创建自定义 Hibernate 类型,因为您可以使用以下依赖项通过 Maven Central 简单地获取它:

<dependency>
    <groupId>com.vladmihalcea</groupId>
    <artifactId>hibernate-types-52</artifactId>
    <version>${hibernate-types.version}</version> 
</dependency> 

有关更多信息,请查看Hibernate Types 开源项目。

然后你可以简单地声明你类的新类型。

@TypeDef(
    name = "jsonb-node", 
    typeClass = JsonNodeBinaryType.class
)

实体映射将如下所示:

@Type(type = "json-node")
@Column(columnDefinition = "json")
private JsonNode json;

【讨论】:

    【解决方案2】:

    创建响应而不将逻辑放入实体 setter/getter,不依赖第三方:

    ObjectNode node = JsonNodeFactory.instance.objectNode();
    node.put("name", cat.getName());
    node.set("json", new ObjectMapper().readTree(cat.getJson()));
    return Response.ok(node).build();
    

    【讨论】:

      【解决方案3】:

      您可以将JsonNode json 属性定义为@Transient,这样JPA 就不会尝试将其存储在数据库中。但是,jackson 应该能够将它来回转换为 Json。

      然后您可以为 JPA 编写 getter/setter 代码,这样您就可以从 JsonNode 来回转换为 String。您定义了一个 getter getJsonString,它将 JsonNode json 转换为 String。那个可以映射到一个表列,比如'json_string',然后你定义一个setter,你从JPA接收String,并将它解析为JsonNode,这对jackson可用。

      不要忘记将@JsonIgnore 添加到getJsonString,这样Jackson 就不会尝试将json 转换为jsonString。

      @Entity
      @Table(name = "cats")
      public class Cat {
      
        private Long id;
      
        private String name;
      
        @Transient
        private JsonNode json;
      
        @Id
        @GeneratedValue(strategy = GenerationType.AUTO)
        public Long getId() {
          return id;
        }
      
        @Column(name ="name")
        public String getName() {
          return name;
        }
      
        public void setName(String name) {
          this.name = name;
        }
      
        public void setId(Long id) {
          this.id = id;
        }
      
        // Getter and setter for name
      
        @Transient
        public JsonNode getJson() {
          return json;
        }
      
        public void setJson(JsonNode json) {
          this.json = json;
        }
      
      
        @Column(name ="jsonString")
        public String getJsonString() {
          return this.json.toString();
        }
      
        public void setJsonString(String jsonString) {
          // parse from String to JsonNode object
          ObjectMapper mapper = new ObjectMapper();
          try {
            this.json = mapper.readTree(jsonString);
          } catch (Exception e) {
            e.printStackTrace();
          }
        }
      }
      

      【讨论】:

      • 有点奇怪,但是 json.asText() 不起作用。 json.toString() 有效
      • 当我使用 JPA 时,这个 @JsonIgnore 列是 NULL
      • 能否调试一下,看看get/setJsonString上json的值是多少?
      • get/setJsonString 工作正常。使用 entityManager.persist(cat) 后,我在数据库中有 NULL
      • 我可以删除 @Column(name ="json_string") - 结果是一样的
      猜你喜欢
      • 2019-09-08
      • 2011-08-26
      • 2021-01-24
      • 2023-02-16
      • 2018-03-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多