xmlmapper new deserialize convert jaxb jackson

new - Objeto Jarsh Umarshall con campos de subrayado y camelCase entre Jackson y JAXB



xmlmapper jackson (2)

Al usar JAXB (2.2) y Jackson (1.9.13), tengo problemas para desmarcar el siguiente objeto JSON en mis POJOs

{ "userId": "foo", "group_id": "bar" }

Tenga en cuenta que la carga útil contiene tanto camelCase como un campo de subrayado.

El POJO generado por xjc para mi esquema XML es el siguiente:

public class User { @XmlElement(required = true) protected String userId; @XmlElement(name = "group_id", required = true) protected String groupId; public String getUserId() { return userId; } public void setUserId(String value) { this.userId = value; } public String getGroupId() { return groupId; } public void setGroupId(String value) { this.groupId = value; } }

Jackson falla con la siguiente excepción:

org.codehaus.jackson.map.exc.UnrecognizedPropertyException: Unrecognized field "group_id"

Lo que intenté hasta ahora y fallé

1. Use el enlace JAXB underscoreBinding="asCharInWord"

Usando el siguiente enlace JXB en mi esquema XML

<jxb:globalBindings underscoreBinding="asCharInWord"/>

Genera el siguiente POJO:

public class User { @XmlElement(required = true) protected String userId; @XmlElement(name = "group_id", required = true) protected String groupId; public String getUserId() { return userId; } public void setUserId(String value) { this.userId = value; } public String getGroup_Id() { return groupId; } public void setGroup_Id(String value) { this.groupId = value; } }

Tenga en cuenta que JAXB ahora genera setters / getters con guión bajo para las ID de grupo, pero el campo group_id todavía se convierte a CamelCase. El mapeador de objetos de Jackson parece ignorar los nombres de los group_id / definidores de propiedades y aún no puede asignar group_id a groupId .

2. Jackson estrategia de nomenclatura de propiedad

Usando PropertyNamingStrategy de Jackson CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES Puedo convertir group_id a groupId , pero ahora el asignador de objetos falla en la propiedad userId JSON.

3. Agregue una anotación JSONProperty a groupId

Agregar una JSONProperty a los JSONProperty generados por JAXB de vainilla realmente funciona

public class User { /* ... */ @XmlElement(name = "group_id", required = true) @JSONProperty("group_id") protected String groupId; /* ... */ }

Sin embargo, mi esquema XML es enorme y la instrumentación manual de las clases generadas no es factible, ya que generamos nuestras clases a menudo.

¿Qué tengo que hacer?

Veo las siguientes dos opciones restantes para manejar este problema:

  1. Implemente un complemento JAXB que agregue una anotación de JSONProperty a cada XMLElement con nombres de subrayado (mi próximo enfoque preferido)
  2. Use un generador de nombres personalizado para XJC como se describe en this respuesta de Stackoverflow.

¿Me he perdido lo obvio? gracias por tus pensamientos


¿Ha intentado anotar el atributo groupId en su clase de usuario con @JsonProperty("group_id") ? Esto debería funcionar (probado y comprobado)!

Si no se encuentra dicha anotación en un atributo, el asignador de Jackson solo considerará el nombre del atributo tal como está, de lo contrario, el valor provisto se usará para la deserialización JSON. Aquí es cómo debe verse su clase de User :

public class User { private String userId; @JsonProperty("group_id") private String groupId;

Esto debería asignarse a su JSON

{"userId": "foo","group_id": "bar"}

Si está utilizando CXF (o cualquier otro marco de Rest) basado en Jackson, sugiero leer la siguiente breve publicación del blog que detalla cómo configurar el JacksonJsonProvider en CXF para lograr la serialización y la deserialización de / a Java de / a JSON Snake Datos formateados de caso (subrayado)

https://mahichir.wordpress.com/2015/07/08/cxf-configuration-to-produce-json-snake-case-underscore-case-formatted-data-using-jackson-json-library/


Encontré una posible solución a su problema, desde un caso similar, en . ¿Cómo extraer ObjectMapper del cliente JAX-RS?

Una vez que tenga acceso a Object Mapper, puede configurar su propio proveedor de anotaciones. Uno que ahora se ha eliminado como un módulo separado, ya que jackson 2.0 es el módulo jaxb.

Aquí está la respuesta, aunque la modifiqué para que cumpla con el módulo Jaxb 2.4.4 de Jackson y la API 2.3.2 de Jackson:

public final static JacksonJsonProvider JACKSON_JSON_PROVIDER = new JacksonJaxbJsonProvider().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false).configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false); public final static ObjectMapper OBJECT_MAPPER = JACKSON_JSON_PROVIDER.locateMapper(Object.class, MediaType.APPLICATION_JSON_TYPE); public final static Client CLIENT = ClientBuilder.newClient().register(JACKSON_JSON_PROVIDER);

Esto requiere el archivo jar: jackson-module-jaxb-annotations-2.xxjar para que jackson pueda cargarlo detrás de la escena a través de la interfaz JacksonJaxbProvider.

Para tu versión de Jackson, creo que el código jaxb todavía está en él. Así que puedes referirte a una forma similar usando http://wiki.fasterxml.com/JacksonJAXBAnnotations