validator tutorial online generar example java json enums jackson jackson-modules

java - tutorial - Genere el Esquema Json de POJO con un giro



json schema tutorial (2)

Parece que no es posible usar las instrucciones que encontré usando databind. Sin embargo, encontré otro módulo de jackson que parece funcionar bien. Curiosamente, varios de los objetos tienen el mismo nombre.

TLDR: use objetos del paquete org.codehaus.jackson.map lugar del paquete com.fasterxml.jackson.databind . Si sigues las instrucciones en esta página, entonces lo estás haciendo mal. Simplemente usa el módulo jackson-mapper en su lugar.

Aquí está el código para futuros usuarios de Google:

private static String getJsonSchema(Class clazz) throws IOException { org.codehaus.jackson.map.ObjectMapper mapper = new ObjectMapper(); //There are other configuration options you can set. This is the one I needed. mapper.configure(SerializationConfig.Feature.WRITE_ENUMS_USING_TO_STRING, true); JsonSchema schema = mapper.generateJsonSchema(clazz); return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(schema); }

Lo que tengo:

Estoy generando un esquema JSON de un pojo. Mi código para generar el esquema se ve así:

ObjectMapper mapper = new ObjectMapper(); TitleSchemaFactoryWrapper visitor = new TitleSchemaFactoryWrapper(); mapper.acceptJsonFormatVisitor(clazz, visitor); JsonSchema schema = visitor.finalSchema(); schemas.put(clazz, mapper.writerWithDefaultPrettyPrinter().writeValueAsString(schema));

Estoy generando varios esquemas a través del código anterior. Uno de los pojos tiene una enumeración interna incorporada para limitar los valores posibles, así:

public class MyClass { @JsonProperty("name") private String name; @JsonProperty("startDayOfWeek") private MyClass.StartDayOfWeek startDayOfWeek; /** * The ID of a timezone returned by the timezones route. * */ @JsonProperty("timezone") private String timezone; @JsonIgnore private Map<String, Object> additionalProperties = new HashMap<String, Object>(); /** * * @return * The startDayOfWeek */ @JsonProperty("startDayOfWeek") public MyClass.StartDayOfWeek getStartDayOfWeek() { return startDayOfWeek; } /** * * @param startDayOfWeek * The startDayOfWeek */ @JsonProperty("startDayOfWeek") public void setStartDayOfWeek(MyClass.StartDayOfWeek startDayOfWeek) { this.startDayOfWeek = startDayOfWeek; } public static enum StartDayOfWeek { MONDAY("Monday"), TUESDAY("Tuesday"), WEDNESDAY("Wednesday"), THURSDAY("Thursday"), FRIDAY("Friday"), SATURDAY("Saturday"), SUNDAY("Sunday"); private final String value; private static Map<String, MyClass.StartDayOfWeek> constants = new HashMap<String, MyClass.StartDayOfWeek>(); static { for (MyClass.StartDayOfWeek c: values()) { constants.put(c.value, c); } } private StartDayOfWeek(String value) { this.value = value; } @JsonValue @Override public String toString() { return this.value; } @JsonCreator public static MyClass.StartDayOfWeek fromValue(String value) { MyClass.StartDayOfWeek constant = constants.get(value); if (constant == null) { throw new IllegalArgumentException(value); } else { return constant; } } } }

El código anterior debe limitar los posibles valores de Cadena en los datos JSON que se transfieren a "Lunes", "Martes", "Miércoles", etc.

Cuando ejecuto el generador de esquemas en el código en cuestión, espero obtener algo como el siguiente esquema:

{ "type" : "object", "javaType" : "my.package.MyClass", "properties": { "startDayOfWeek" : { "type" : "string", "enum" : [ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" ] } } }

pero en cambio estoy obteniendo esto:

{ "type" : "object", "id" : "urn:jsonschema:my:package:MyClass", "title" : "Lmy/package/MyClass;", "properties" : { "startDayOfWeek" : { "type" : "string" } } }

He hecho algunas búsquedas en el código fuente del Módulo Schema de Jackson y descubrí que lo que está sucediendo es que Jackson está usando ".toString ()" como el método de serialización predeterminado para los tipos enum, pero lo que necesito hacer es crear la línea que parece esto basado en StartDayOfWeek.values() :

"enum" : [ "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday" ]

¿Alguien sabe cómo hacer eso?


La respuesta de Storme hace referencia a org.codehaus , que es una versión anterior de jackson. Lo siguiente es similar pero usa fasterxml (versión más nueva).

Pom:

<dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-core</artifactId> <version>2.7.1</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-databind</artifactId> <version>2.7.1</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.core</groupId> <artifactId>jackson-annotations</artifactId> <version>2.7.1</version> </dependency> <dependency> <groupId>com.fasterxml.jackson.module</groupId> <artifactId>jackson-module-jsonSchema</artifactId> <version>2.1.0</version> </dependency>

Código:

import ...TargetClass; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.jsonschema.JsonSchema; import java.io.IOException; public final class JsonSchemaGenerator { private JsonSchemaGenerator() { }; public static void main(String[] args) throws IOException { System.out.println(JsonSchemaGenerator.getJsonSchema(TargetClass.class)); } public static String getJsonSchema(Class clazz) throws IOException { ObjectMapper mapper = new ObjectMapper(); mapper.configure(SerializationFeature.WRITE_ENUMS_USING_TO_STRING, true); JsonSchema schema = mapper.generateJsonSchema(clazz); return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(schema); } }