JSON 到带有自定义注释的 POJO

JSON to POJO with custom annotations

我正在尝试在我从 JSON 生成的 Java 代码中包含 Spring 引导注释,如下所示:

@Entity
public class Person {
...
}

@Repository
public interface PersonRepository extends CrudRepository<Person, Long> 
{
}

我正在使用 this tutorial 从 JSON 转换为 POJO。我可以向我的 json 文件添加什么以使生成的 Java 类 包含注释 @Entity 和 @Repository?我还没有找到关于如何提供自定义注释的教程或解释。

jsonschema2pojo 看起来它可以在生成 类 时使用自定义注释器工作,但我想知道 Jackson 是否有任何内置的东西可以轻松允许自定义注释?

jsonschema2pojo 的 customAnnotator 允许我向生成的 java 文件添加自定义注释。它的烦恼是你的注释器 class 必须在一个单独的项目中,并且必须包含在插件中 Here's why

将依赖项添加到您的 pom.xml

<dependency>
    <groupId>org.jsonschema2pojo</groupId>
    <artifactId>jsonschema2pojo-core</artifactId>
    <version>0.4.0</version>
</dependency>

将插件添加到 pom.xml 插件

<plugin>
    <groupId>org.jsonschema2pojo</groupId>
    <artifactId>jsonschema2pojo-maven-plugin</artifactId>
    <version>0.5.1</version>
    <dependencies>
        <!-- NOTE: Your annotator MUST come from a dependency -->
        <dependency>
            <groupId>ANNOTATOR_GROUP_ID</groupId>
            <artifactId>ANNOTATOR_ARTIFACT</artifactId>
            <version>0.0.1-SNAPSHOT</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            <scope>compile</scope>
            <version>1.5.2.RELEASE</version>
        </dependency>
       <!-- NOTE: Any annotation used must have its dependency here!!! -->
    </dependencies>
    <configuration>
        <sourceDirectory>${basedir}/src/main/resources/schema</sourceDirectory>
        <targetPackage>com.test.gen</targetPackage>
        <useCommonsLang3>true</useCommonsLang3>
        <customAnnotator>com.fully.qualified.path.YourAnnotator</customAnnotator>
    </configuration>
    <executions>
        <execution>
            <goals>
                <goal>generate</goal>
            </goals>
        </execution>
    </executions>
</plugin>

一个单独的项目中创建自定义注释器class。

package com.deere.gtin_k.pdeaas.work_manager.application;

import com.fasterxml.jackson.databind.JsonNode;
import com.sun.codemodel.JDefinedClass;
import com.sun.codemodel.JFieldVar;
import org.jsonschema2pojo.AbstractAnnotator;

import javax.persistence.Entity;

public class HibernateAnnotator extends AbstractAnnotator {

    @Override
    public void propertyField(JFieldVar field, JDefinedClass clazz, String propertyName, JsonNode propertyNode) {
        super.propertyField(field, clazz, propertyName, propertyNode);

        // Note: does not have to be the propertyName, could be the field or propertyNode that is verified.
        if (propertyName.equals("entity")) {
            clazz.annotate(Entity.class);
        }
    }
}

最后,json 文件:

{
  "title": "Person",
  "type": "object",
  "properties": {
    "entity": true,
    "name": {
      "type": "string"
    }
  }
}

最终结果:

package com.test.gen;

import java.util.HashMap;
import java.util.Map;
import javax.persistence.Entity;
import com.fasterxml.jackson.annotation.JsonAnyGetter;
import com.fasterxml.jackson.annotation.JsonAnySetter;
import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.annotation.JsonPropertyOrder;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;


/**
 * Person
 * <p>
 * 
 * 
 */
@JsonInclude(JsonInclude.Include.NON_NULL)
@Entity
@JsonPropertyOrder({
    "entity",
    "name"
})
public class Person {

    @JsonProperty("entity")
    private Object entity;
    ...
}

我希望有更简单的方法来做到这一点。

就我而言,我需要按照 https://www.baeldung.com/javax-validations-enums(第 5 个选项)

中的建议添加 @ValueOfEnum(enumClass = com.mycompany.SampleType)

所以我调整了覆盖方法

@Override
public void propertyField(JFieldVar field, JDefinedClass clazz, String propertyName, JsonNode propertyNode) {
    super.propertyField(field, clazz, propertyName, propertyNode);

    if (propertyNode.get("enumClass") != null) {
        try {
            field.annotate(ValueOfEnum.class).param("enumClass",  Class.forName(propertyNode.get("enumClass").asText()));
        } catch (ClassNotFoundException e) {
            System.err.println("'Not able to add @ValueOfEnum(enumClass = " + propertyNode.get("enumClass").asText() + "' annotation to property :" + propertyName + ". Enum not found in the classpath");
        }
    }
}

还要确保 ValueOfEnum,并且插件可以使用实际的枚举。在 pom.xml

添加插件依赖

注解修饰的替代

我在猜测问题背后的意图:

  • 您有从 json 模式生成的 POJO
  • 您想使用 ORM (JPA) 将 POJO 作为实体进行管理
  • 您希望将 Spring 数据与 JPA 实体一起使用

也许尝试使用 JPA 注释装饰生成的 POJO 的替代方法是使用 orm.xml。这可用于定义实体并与您的 ORM 集成,作为注释 POJO 的替代方法。这对于您无法自己进行更改的现有 类 或者可能在生成代码的情况下很有用。

使用您生成的 POJO,将 orm.xml 添加到您的 ${project.basedir}/src/main/resources/META-INF 而不是 添加注释

也许像

orm.xml

<?xml version="1.0" encoding="UTF-8" ?>
<entity-mappings xmlns="http://java.sun.com/xml/ns/persistence/orm"
                 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                 xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm http://java.sun.com/xml/ns/persistence/orm_2_0.xsd"
                 version="2.0">

    <entity class="com.test.gen.Person" access="FIELD">
        <table name="person"/>
        <attributes>
            <id name="id">
                <generated-value strategy="AUTO"/>
            </id>
            <basic name="firstname">
                <column name="firstname" length="200"/>
            </basic>
        </attributes>
    </entity>

</entity-mappings>