杰克逊克服下划线支持骆驼案

Posted

技术标签:

【中文标题】杰克逊克服下划线支持骆驼案【英文标题】:Jackson overcoming underscores in favor of camel-case 【发布时间】:2012-05-18 03:44:19 【问题描述】:

我从互联网上检索一个 JSON 字符串;像我见过的大多数 JSON 一样,它包含由下划线分隔的长键。本质上,我的目标是将 JSON 反序列化为 java 对象,但我不在 java 代码中使用下划线。

例如,我可能有一个 User 类和骆驼案例中的 firstName 字段,同时我需要以某种方式告诉 Jackson 将 first_name 键从 JSON 映射到 firstName 类字段。有可能吗?

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

【问题讨论】:

【参考方案1】:

您可以配置ObjectMapper 将驼峰式大小写转换为带下划线的名称:

objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);

或者用这个注解来注解一个特定的模型类:

@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)

在 Jackson 2.7 之前,该常量被命名为:

PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES

【讨论】:

请注意,这只在 Jackson 1.9 中引入。 @deprecated 从 2.7 开始使用 SNAKE_CASE; @Ramswaroop 是的,这让杰克逊既说话又期待蛇案例 从 Jackson 2.12 开始是 PropertyNamingStrategies.SNAKE_CASE 在 Jackson 2.12+ 中使用注释时:@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)【参考方案2】:

如果是spring boot应用,在application.properties文件中使用

spring.jackson.property-naming-strategy=SNAKE_CASE

或者用这个注解来注解模型类。

@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)

【讨论】:

如果我用“@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)”注释我的班级,它就可以工作。但是如果我在“application.properties”中使用“spring.jackson.property-naming-strategy=SNAKE_CASE”,它不会。我正在使用“Spring Boot (v2.0.0.BUILD-SNAPSHOT)”。你有什么想法吗? 这里一样,spring.jackson.property-naming-strategy=SNAKE_CASE 不起作用,我使用的是 Spring Boot 2.0 这里一样,spring.jackson.property-naming-strategy=SNAKE_CASE 不起作用,我使用的是 Spring Boot 2.0.5。但是使用注释对我有用 也许你的ObjectMapper不是由Spring创建的?使用返回 ObjectMapper 的 @Bean 方法创建 @Configuration 类。不确定这是否有必要。 我正在使用 Spring boot 2.4.1 和 spring.jackson.property-naming-strategy=SNAKE_CASE 为我工作【参考方案3】:

您应该在要更改默认名称映射的字段上使用@JsonProperty

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

欲了解更多信息:API

【讨论】:

不要这样做,否则您将不得不为每个属性都这样做。请参阅下面 thehpi 的回复。 我只能注释一个属性,但它确实改变了生成字符串中属性的顺序:注释的属性最后出现。 (杰克逊 2.3.0) @RyanShillington - 如果我错了,请纠正我,但如果您解析的 JSON 字符串不使用一致的格式,即同时使用驼峰式和下划线,这是您唯一的选择?跨度> @DavidR 没错。我假设您无法修复源数据?太糟糕了。 @PaulTsai 好的,所以请随意使用它们 :)【参考方案4】:

如果您想在单个类中使用此功能,可以使用 PropertyNamingStrategy 和 @JsonNaming,如下所示:

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

    String businessName;
    String businessLegalName;


将序列化为:


    "business_name" : "",
    "business_legal_name" : ""

由于Jackson 2.7 LowerCaseWithUnderscoresStrategySnakeCaseStrategy 弃用,所以你应该使用:

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

    String businessName;
    String businessLegalName;


【讨论】:

【参考方案5】:

上述关于@JsonPropertyCAMEL_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);

【讨论】:

Spring Boot 的替代方案,如果您使用的是 Spring Boot 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 @zapl 是的,你是对的,我可能提到了杰克逊的版本而不是 spring-boot 的版本。让我删除该评论以避免混淆。 从 Jackson 的 2.7 版开始,它是 SNAKE_CASE。这对我有用:final ObjectMapper objectMapper = new ObjectMapper().setPropertyNamingStrategy( PropertyNamingStrategy.SNAKE_CASE);【参考方案6】:

当前的最佳做法是在application.yml(或properties)文件中配置Jackson。

例子:

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 实例正在加载并覆盖这个实例吗?你能确认甚至这个 bean 正在加载吗? 也试一试 DuffJ 的解决方案。非常相似。 我认为调整属性是正确的方法;并推荐了。这与此相同。 @WesternGun 好电话。如果可能,我倾向于通过 yaml/properties 执行此操作。【参考方案7】:

这里很少有答案表明以下两种不同版本的 Jackson 库的两种策略:

对于杰克逊 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: kebab-case 不是snake_case ;-)【参考方案8】:

注释所有模型类在我看来是一种矫枉过正,而 Kenny 的回答对我不起作用https://***.com/a/43271115/4437153。序列化的结果还是驼峰式的。

我意识到我的弹簧配置有问题,所以我不得不从另一个方面解决这个问题。希望有人觉得它有用,但如果我在做违反 springs 规则的事情,请告诉我。

Spring MVC 5.2.5 和 Jackson 2.11.2 的解决方案

@Configuration
@EnableWebMvc
public class WebConfig implements WebMvcConfigurer 
    @Override
    public void configureMessageConverters(List<HttpMessageConverter<?>> converters) 
        ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);           

        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        converter.setObjectMapper(objectMapper);
        converters.add(converter);
    

【讨论】:

【参考方案9】:

为了注释模型类使用:

@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)

代替:

@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)

自 2.12 起已弃用。

【讨论】:

【参考方案10】:

    您可以在我们类的字段上使用@JsonProperty 注解将字段映射到我们JSON 中的确切名称

    @JsonProperty("my_name")
    private String myName;
    

    可以在类上使用@JsonNaming注解,所有字段都会使用snake case反序列化

    @JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) 
    public class MyClassWithSnakeStrategy  ... 
    

    您可以使用 ObjectMapper 上的 setPropertyNamingStrategy 方法来配置它以进行所有序列化

    ObjectMapper objectMapper = new ObjectMapper() .setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);

【讨论】:

以上是关于杰克逊克服下划线支持骆驼案的主要内容,如果未能解决你的问题,请参考以下文章

在ruby中将骆驼大小写转换为下划线大小写

帕斯卡命名法和骆驼命名法

将骆驼大小写转换为人类可读的字符串?

把骆驼命名法的变量,变为大写字母变小写且之前加下划线

热到让杰克逊在 Spring Boot REST API 中按需使用蛇案例/骆驼案例?

Java - 基本语法