2012-05-09 17 views
85

Recupero una cadena JSON de internet; como la mayoría de JSON que he visto, incluye teclas largas que están separadas por guiones bajos. Básicamente, mi objetivo es deserializar JSON en objetos java, pero no uso guiones bajos en el código java.Jackson superando guiones bajos a favor de camel-case

Por ejemplo, podría haber una clase User con firstName campo en camello caso, al mismo tiempo que necesito alguna manera de decirle Jackson para mapear first_name clave de JSON para firstName campo de clase. ¿Es posible?

class User{ 
    protected String firstName; 
    protected String getFirstName(){return firstName;} 
} 

Respuesta

59

Se debe utilizar la @JsonProperty en el campo que desea cambiar la asignación de nombre por defecto.

class User{ 
    @JsonProperty("first_name") 
    protected String firstName; 
    protected String getFirstName(){return firstName;} 
} 

Para más información: la API

+49

No haga esto, o de lo contrario tendrá que hacerlo por cada propiedad. Ver la respuesta de thehpi a continuación. –

+0

Solo pude anotar una propiedad, pero cambió el orden de las propiedades en la cadena generada: las propiedades anotadas aparecieron al final. (Jackson 2.3.0) – eebbesen

+1

@RyanShillington - Corrígeme si me equivoco, pero esta es tu única opción si la cadena JSON desde la que estás analizando no usa un formato coherente, es decir, usa tanto camelCase como guión bajo. – DavidR

218

Puede configurar el ObjectMapper para convertir el caso en camello a los nombres con un guión

this.objectMapper.setPropertyNamingStrategy(
    PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES); 
+5

Tenga en cuenta que esto solo se introdujo en Jackson 1.9. –

+38

@deprecated Since 2.7 use SNAKE_CASE en su lugar; – Thermech

+0

una qq: cuando uso la estrategia de nombres de snake_case, ¿los archivos json con guiones bajos se deserializarán a camel case? –

22

Las respuestas anteriores con respecto a @JsonProperty y CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES son 100% exacto, aunque algunas personas (como yo) podrían estar tratando de hacer esto dentro de una aplicación Spring MVC con configuración basada en código. Aquí está el código de ejemplo (que tengo dentro Beans.java) para lograr el efecto deseado:

@Bean 
public ObjectMapper jacksonObjectMapper() { 
    return new ObjectMapper().setPropertyNamingStrategy(
      PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES); 
} 
+8

Una alternativa para Spring Boot, si está utilizando Spring Boot <= 1.3, en 'application.properties' add' spring.jackson.property-naming-strategy = CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCOR ES'. Para Spring Boot 1.4, use 'spring.jackson.property-naming-strategy = SNAKE_CASE' en su lugar. –

+1

@zapl sí, tienes razón, probablemente mencioné la versión de jackson en lugar de la versión de Spring-boot. Déjame borrar ese comentario para evitar confusiones. –

+1

A partir de la versión 2.7 de Jackson es SNAKE_CASE. Esto funcionó para mí: 'ObjectMapper final objectMapper = new ObjectMapper(). SetPropertyNamingStrategy ( PropertyNamingStrategy.SNAKE_CASE);' – Jonathan

17

Si desea que esta para una sola clase, se puede utilizar el PropertyNamingStrategy con el @JsonNaming, algo como esto:

@JsonNaming(PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy.class) 
public static class Request { 

    String businessName; 
    String businessLegalName; 

} 

serializará a:

{ 
    "business_name" : "", 
    "business_legal_name" : "" 
} 
34

Si es una aplicación de inicio de la primavera, application.properties En archivo, sólo tiene que utilizar

spring.jackson.property-nombres-estrategia = SNAKE_CASE

o anotar la clase del modelo con esta anotación.

@JsonNaming (PropertyNamingStrategy.SnakeCaseStrategy.class)

+0

Si anoto mi clase con la "@JsonNaming (PropertyNamingStrategy.SnakeCaseStrategy.class)" funciona. Pero si uso "spring.jackson.property-naming-strategy = SNAKE_CASE" en "application.properties" no lo hará. Estoy usando "Spring Boot (v2.0.0.BUILD-SNAPSHOT)". Tienes alguna idea ? – Bruno

4

Para las versiones más nuevas de la primavera, Gotas este archivo de configuración en su proyecto (o simplemente tomar el Bean). Encontré que esto funciona tanto para el mapeo de respuesta como para el mapeo de cuerpo de solicitud.

import com.fasterxml.jackson.databind.PropertyNamingStrategy; 
import org.springframework.context.annotation.Bean; 
import org.springframework.context.annotation.Configuration; 
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder; 

@Configuration 
public class JacksonConfiguration { 

    @Bean 
    public Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder() { 
     return new Jackson2ObjectMapperBuilder() 
       .propertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE); 
    } 

} 
+0

Esto no funcionó para mí. – user216661

+0

¿Sabe si tiene otra instancia de jackson2objectmapper cargándose y anulando esta? ¿Y puedes confirmar que incluso este bean se está cargando? –

+0

Dale también un giro a la solución de DuffJ. Es bastante similar. –

Cuestiones relacionadas