简体   繁体   English

Jackson 克服下划线,支持驼峰式

[英]Jackson overcoming underscores in favor of camel-case

I retrieve a JSON string from internet;我从互联网上检索了一个 JSON 字符串; like most JSON I've seen it includes long keys that are separated by underscores.像大多数 JSON 我见过它包括由下划线分隔的长键。 Essentially, my goal is to deserialize JSON into java-objects, but I don't use underscores in java-code.本质上,我的目标是将 JSON 反序列化为 java 对象,但我不在 java 代码中使用下划线。

For instance, I might have a User class with firstName field in camel-case, simultaneously I need somehow to tell Jackson to map first_name key from JSON to firstName class field. For instance, I might have a User class with firstName field in camel-case, simultaneously I need somehow to tell Jackson to map first_name key from JSON to firstName class field. Is it possible?可能吗?

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

You can configure the ObjectMapper to convert camel case to names with an underscore:您可以配置ObjectMapper将驼峰式大小写转换为带下划线的名称:

objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);

Or annotate a specific model class with this annotation:或者使用此注释注释特定的模型类:

@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)

Before Jackson 2.7, the constant was named:在 Jackson 2.7 之前,常量被命名为:

PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES

If its a spring boot application, In application.properties file, just use如果它是一个 spring boot 应用程序,在 application.properties 文件中,只需使用

spring.jackson.property-naming-strategy=SNAKE_CASE spring.jackson.property-naming-strategy=SNAKE_CASE

Or Annotate the model class with this annotation.或者用这个注解注解模型类。

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

You should use the @JsonProperty on the field you want to change the default name mapping.您应该在要更改默认名称映射的字段上使用@JsonProperty

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

For more info: the API更多信息: API

If you want this for a Single Class, you can use the PropertyNamingStrategy with the @JsonNaming , something like this:如果您希望将其用于单个类,则可以将PropertyNamingStrategy@JsonNaming 一起使用,如下所示:

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

    String businessName;
    String businessLegalName;

}

Will serialize to:将序列化为:

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

Since Jackson 2.7 the LowerCaseWithUnderscoresStrategy in deprecated in favor of SnakeCaseStrategy , so you should use:由于Jackson 2.7不推荐使用LowerCaseWithUnderscoresStrategy以支持SnakeCaseStrategy ,因此您应该使用:

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

    String businessName;
    String businessLegalName;

}

The above answers regarding @JsonProperty and CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES are 100% accurate, although some people (like me) might be trying to do this inside a Spring MVC application with code-based configuration.以上关于@JsonPropertyCAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES答案是 100% 准确的,尽管有些人(像我一样)可能会尝试在具有基于代码的配置的 Spring MVC 应用程序中执行此操作。 Here's sample code (that I have inside Beans.java ) to achieve the desired effect:这是实现预期效果的示例代码(我在Beans.java ):

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

The current best practice is to configure Jackson within the application.yml (or properties ) file.当前的最佳实践是在application.yml (或properties )文件中配置 Jackson。

Example:例子:

spring:
  jackson:
    property-naming-strategy: SNAKE_CASE

If you have more complex configuration requirements, you can also configure Jackson programmatically.如果您有更复杂的配置需求,您还可以通过编程方式配置 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
    }

} 

There are few answers here indicating both strategies for 2 different versions of Jackson library below:这里很少有答案表明以下两种不同版本的 Jackson 库的两种策略:

For Jackson 2.6.*对于杰克逊 2.6.*

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

For Jackson 2.7.*对于杰克逊 2.7.*

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

In order to annotate the model class use:为了注释模型类,请使用:

@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)

Instead of:代替:

@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)

It was deprecated since 2.12.它从 2.12 开始被弃用。

Annotating all model classes looks to me as an overkill and Kenny's answer didn't work for me https://stackoverflow.com/a/43271115/4437153 .注释所有模型类在我看来是一种矫枉过正,肯尼的回答对我不起作用https://stackoverflow.com/a/43271115/4437153 The result of serialization was still camel case.连载的结果还是驼峰式。

I realised that there is a problem with my spring configuration, so I had to tackle that problem from another side.我意识到我的弹簧配置有问题,所以我不得不从另一个方面解决这个问题。 Hopefully someone finds it useful, but if I'm doing something against springs' rules then please let me know.希望有人觉得它有用,但如果我在做违反弹簧规则的事情,请告诉我。

Solution for Spring MVC 5.2.5 and Jackson 2.11.2 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);
    }
}
  1. You can use the @JsonProperty annotation on the fields of our class to map the fields to the exact names in our JSON您可以在我们类的字段上使用 @JsonProperty 注释将字段映射到我们 JSON 中的确切名称

    @JsonProperty("my_name") private String myName;
  2. You can use @JsonNaming annotation on the class, and all fields will be deserialized using snake case可以在类上使用@JsonNaming注解,所有字段都会使用snake case反序列化

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

} }

  1. You can use the setPropertyNamingStrategy method on ObjectMapper to configure it for all serialization您可以使用 ObjectMapper 上的 setPropertyNamingStrategy 方法来配置它以进行所有序列化

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

PropertyNamingStrategy should be replaced with PropertyNamingStrategies for @JsonNaming PropertyNamingStrategy应替换为 @JsonNaming 的PropertyNamingStrategies

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM