杰克逊克服下划线支持骆驼案
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
LowerCaseWithUnderscoresStrategy
被SnakeCaseStrategy
弃用,所以你应该使用:
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public static class Request
String businessName;
String businessLegalName;
【讨论】:
【参考方案5】:上述关于@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);
【讨论】:
Spring Boot 的替代方案,如果您使用的是 Spring Boot application.properties 添加spring.jackson.property-naming-strategy=CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES
。对于 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);
【讨论】:
以上是关于杰克逊克服下划线支持骆驼案的主要内容,如果未能解决你的问题,请参考以下文章