writevalueasstring serialize parse deserialize java json serialization jackson

java - serialize - ¿Por qué cuando un constructor está anotado con @JsonCreator, sus argumentos deben ser anotados con @JsonProperty?



objectmapper writevalueasstring (6)

Cuando entiendo this correctamente, reemplazas el constructor predeterminado con uno parametrizado y por lo tanto tienes que describir las claves JSON que se usan para llamar al constructor.

En Jackson, cuando anota un constructor con @JsonCreator , debe anotar sus argumentos con @JsonProperty . Entonces este constructor

public Point(double x, double y) { this.x = x; this.y = y; }

se convierte en esto:

@JsonCreator public Point(@JsonProperty("x") double x, @JsonProperty("y") double y) { this.x = x; this.y = y; }

No entiendo por qué es necesario. ¿Puede usted explicar por favor?


Debido a que el bytecode de Java no conserva los nombres del método o los argumentos del constructor.



Jackson tiene que saber en qué orden pasar campos de un objeto JSON al constructor. No es posible acceder a los nombres de los parámetros en Java utilizando la reflexión, por eso debe repetir esta información en anotaciones.


Los nombres de los parámetros normalmente no son accesibles por el código de Java en tiempo de ejecución (porque el compilador los reemplaza), por lo que si desea esa funcionalidad necesita usar la funcionalidad incorporada de Java 8 o usar una biblioteca como ParaNamer para obtener acceso lo.

Entonces, para no tener que utilizar anotaciones para los argumentos del constructor al usar Jackson, puede hacer uso de cualquiera de estos 2 módulos de Jackson:

jackson-module-parameter-names

Este módulo le permite obtener argumentos de constructor sin anotaciones cuando usa Java 8 . Para usarlo primero necesita registrar el módulo:

ObjectMapper mapper = new ObjectMapper(); mapper.registerModule(new ParameterNamesModule());

Luego compila tu código usando la bandera -parameters:

javac -parameters ...

Enlace: https://github.com/FasterXML/jackson-modules-java8/tree/master/parameter-names

jackson-module-paranamer

Esta otra simplemente requiere que registre el módulo o configure una introspección de anotación (pero no ambas como se señala en los comentarios). Le permite usar argumentos de constructor sin anotación en las versiones de Java anteriores a la 1.8 .

ObjectMapper mapper = new ObjectMapper(); // either via module mapper.registerModule(new ParanamerModule()); // or by directly assigning annotation introspector (but not both!) mapper.setAnnotationIntrospector(new ParanamerOnJacksonAnnotationIntrospector());

Enlace: https://github.com/FasterXML/jackson-modules-base/tree/master/paranamer


Tal como se especifica en la documentación de la anotación , la anotación indica que el nombre del argumento se usa como el nombre de la propiedad sin modificaciones, pero se puede especificar en un valor no vacío para especificar un nombre diferente: