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>
我正在尝试在我从 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>