Джексон долає підкреслення на користь верблюда


160

Я отримую рядок JSON з Інтернету; як і більшість JSON, які я бачив, вона включає довгі клавіші, розділені підкресленнями. По суті, моя мета - десеріалізувати JSON в java-об’єкти, але я не використовую підкреслення в java-коді.

Наприклад, у мене може бути Userклас з firstNameполем у випадку з верблюдами, одночасно мені потрібно якось сказати Джексону, щоб він перевів first_nameключ від JSON до firstNameкласового поля. Це можливо?

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

Відповіді:


103

Вам слід скористатись @JsonPropertyполем, у якому потрібно змінити відображення імені за замовчуванням.

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

Для отримання додаткової інформації: API


86
Не робіть цього, інакше вам доведеться робити це для кожної власності. Дивіться відповідь thehpi нижче.
Райан Шиллінгтон

Я зміг зазначити лише одну властивість, але це змінило порядок властивостей у створеній рядку: анотовані властивості з’являлися останніми. (Джексон 2.3.0)
eebbesen

1
@RyanShillington - Виправте мене, якщо я помиляюся, але це ваш єдиний варіант, якщо рядок JSON, з якої ви розбираєтесь, не використовує послідовний формат, тобто використовує як camelCase, так і підкреслення?
DavidR

@DavidR Це правильно. Я припускаю, що ви не можете виправити вихідні дані? Це смокче.
Райан Шиллінгтон

@PaulTsai нормально, тому сміливо користуйтеся ними :)
Alex

351

Ви можете налаштувати ObjectMapperперетворення корпусу верблюда в імена з підкресленням:

objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);

Або анотувати конкретний клас моделі за допомогою цієї примітки:

@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)

До Джексона 2.7 константа була названа:

PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES

5
Зауважте, що це було введено лише в Джексоні 1.9.
Девід Молес

62
@deprecated З 2.7 використовуйте замість SNAKE_CASE;
Термех

1
один qq: коли я використовую стратегію іменування snake_case, чи будуть деріаріалізовані файли json з підкресленнями для справи верблюда?
Ram Patra

2
@Ramswaroop Так, це змушує Джексона говорити і очікувати snake_case
Дрю Стівенс

1
@Ramswaroop Для мене з Jackson 2.7.3 та властивостями, @JsonPropertyпозначеними справедливими (ім'я, що випливає із звичайних camelCaseвластивостей Java), PropertyNamingStrategy.SNAKE_CASEдезаріалізація припинила роботу з camelCase JSON (як я використовував) і вимагала snake_case.
Дрю Стівенс

119

Якщо це додаток для весняного завантаження, у файлі application.properties просто використовуйте

spring.jackson.property-nameing-strategy = SNAKE_CASE

Або Анотувати клас моделі за допомогою цієї примітки.

@JsonNaming (PropertyNamingStrategy.SnakeCaseStrategy.class)


3
Якщо я коментую свій клас "@JsonNaming (PropertyNamingStrategy.SnakeCaseStrategy.class)", він працює. Але якщо я використовую "spring.jackson.property-nameing-strategy = SNAKE_CASE" у "application.properties", він не буде. Я використовую "Spring Boot (v2.0.0.BUILD-SNAPSHOT)". У вас є ідеї?
Бруно

1
тут же, spring.jackson.property-naming-strategy=SNAKE_CASEне працює, я використовую Spring Boot 2.0
soulmachine

1
те ж саме, spring.jackson.property-naming-strategy = SNAKE_CASE не працює, я використовую Spring Boot 2.0.5. Але використання анотації працює для мене
Нео Фам,

Можливо, ваш ObjectMapperне створений весною? Створіть клас @Configuration методом @Bean, який повертає ObjectMapper. Не впевнений, чи потрібно це.
Ondra Žižka

48

Якщо ви хочете цього для одного класу, ви можете використовувати PropertyNamingStrategy за допомогою @JsonNaming , приблизно так:

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

    String businessName;
    String businessLegalName;

}

Буде серіалізуватися на:

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

Оскільки в засуджується на користь , так що ви повинні використовувати:Jackson 2.7LowerCaseWithUnderscoresStrategySnakeCaseStrategy

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

    String businessName;
    String businessLegalName;

}

29

Наведені вище відповіді щодо @JsonPropertyта CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORESє на 100% точними, хоча деякі люди (як я), можливо, намагаються зробити це всередині програми Spring MVC з конфігурацією на основі коду. Ось зразок коду (який у мене всередині Beans.java), щоб досягти бажаного ефекту:

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

9
Альтернатива Spring Boot, якщо ви використовуєте Spring Boot <= 1.3, на application.propertiesдодаток spring.jackson.property-naming-strategy=CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCOR‌​ES. Для Spring Boot 1.4 використовуйте spring.jackson.property-naming-strategy=SNAKE_CASEзамість цього.
Дамп торт

1
@zapl так, ти маєш рацію, напевно, я згадував версію Джексона замість версії весняного завантаження. Дозвольте мені видалити цей коментар, щоб уникнути плутанини.
Ram Patra

1
Станом на версію 2.7 Jackson це SNAKE_CASE. Це працювало для мене: final ObjectMapper objectMapper = new ObjectMapper().setPropertyNamingStrategy( PropertyNamingStrategy.SNAKE_CASE);
Джонатан

12

Поточна найкраща практика - це налаштувати Джексона у файлі application.yml(або properties).

Приклад:

spring:
  jackson:
    property-naming-strategy: SNAKE_CASE

Якщо у вас є складніші вимоги до конфігурації, ви також можете налаштувати Jackson програмно.

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);
        // insert other configurations
    }

} 

Чи знаєте ви, чи є у вас інший екземпляр завантаження jackson2objectmapper і перезапис цього? І чи можете ви підтвердити, що навіть ця квасоля завантажується?
Кенні Кейсон

Також дайте вихору рішення DuffJ. Це досить схоже.
Кенні Кейсон

Я думаю, що налаштування властивостей - це правильний шлях; і рекомендується теж. Це робить те саме, що і це.
WesternGun

@WesternGun гарний дзвінок. Я схильний робити це через yaml / властивості, коли це можливо.
Кенні

6

Тут наведено кілька відповідей, що вказують на обидві стратегії для двох різних версій бібліотеки Джексона:

Для Джексона 2.6. *

ObjectMapper objMapper = new ObjectMapper(new JsonFactory()); // or YAMLFactory()
objMapper.setNamingStrategy(
     PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);

Для Джексона 2.7. *

ObjectMapper objMapper = new ObjectMapper(new JsonFactory()); // or YAMLFactory()
objMapper.setNamingStrategy(
     PropertyNamingStrategy.SNAKE_CASE);

вони знову застаріли деякі значення, тепер у них є KEBAB_CASE, ну!
Калпеш Соні

FTR: шашлик - це не змія;
Рене
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.