Reputation: 2629
I retrieve a JSON string from internet; like most JSON I've seen it includes long keys that are separated by underscores. Essentially, my goal is to deserialize JSON into java-objects, but I don't use underscores in java-code.
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;}
}
Upvotes: 220
Views: 212796
Reputation: 5833
In Jackson 2.12+, you can configure the ObjectMapper
to convert camel case to names with an underscore:
objectMapper.setPropertyNamingStrategy(PropertyNamingStrategies.SNAKE_CASE);
Or annotate a specific model class with this annotation:
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
Before Jackson 2.7, the constant was named:
PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES
Upvotes: 486
Reputation: 3627
If you want this for a Single Class, you can use the PropertyNamingStrategies with the @JsonNaming, annotation, like this:
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public static class Request {
String businessName;
String businessLegalName;
}
Will serialize to:
{
"business_name" : "",
"business_legal_name" : ""
}
Before Jackson 2.7
, use PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy.class
:
@JsonNaming(PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy.class)
public static class Request {
String businessName;
String businessLegalName;
}
From Jackson 2.7
to Jackson 2.12
the LowerCaseWithUnderscoresStrategy
is deprecated in favor of SnakeCaseStrategy
, so you should use:
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
public static class Request {
String businessName;
String businessLegalName;
}
Since Jackson 2.12
the PropertyNamingStrategy.SnakeCaseStrategy
is deprecated in favor of PropertyNamingStrategies.SnakeCaseStrategy
, you should use:
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
public static class Request {
String businessName;
String businessLegalName;
}
Upvotes: 60
Reputation: 29
PropertyNamingStrategy
should be replaced with PropertyNamingStrategies
for @JsonNaming
Upvotes: 0
Reputation: 98
You can use the @JsonProperty annotation on the fields of our class to map the fields to the exact names in our JSON
@JsonProperty("my_name") private String myName;
You can use @JsonNaming annotation on the class, and all fields will be deserialized using snake case
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class) public class MyClassWithSnakeStrategy { ...
}
You can use the setPropertyNamingStrategy method on ObjectMapper to configure it for all serialization
ObjectMapper objectMapper = new ObjectMapper()
.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
Upvotes: 1
Reputation: 131
In order to annotate the model class use:
@JsonNaming(PropertyNamingStrategies.SnakeCaseStrategy.class)
Instead of:
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
It was deprecated since 2.12.
Upvotes: 13
Reputation: 404
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. 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
@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);
}
}
Upvotes: 4
Reputation: 12328
The current best practice is to configure Jackson within the application.yml
(or properties
) file.
Example:
spring:
jackson:
property-naming-strategy: SNAKE_CASE
If you have more complex configuration requirements, you can also configure Jackson programmatically.
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
}
}
Upvotes: 19
Reputation: 5808
There are few answers here indicating both strategies for 2 different versions of Jackson library below:
For Jackson 2.6.*
ObjectMapper objMapper = new ObjectMapper(new JsonFactory()); // or YAMLFactory()
objMapper.setNamingStrategy(
PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
For Jackson 2.7.*
ObjectMapper objMapper = new ObjectMapper(new JsonFactory()); // or YAMLFactory()
objMapper.setNamingStrategy(
PropertyNamingStrategy.SNAKE_CASE);
Upvotes: 6
Reputation: 1420
If its a spring boot application, In application.properties file, just use
spring.jackson.property-naming-strategy=SNAKE_CASE
Or Annotate the model class with this annotation.
@JsonNaming(PropertyNamingStrategy.SnakeCaseStrategy.class)
Upvotes: 142
Reputation: 3573
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. Here's sample code (that I have inside Beans.java
) to achieve the desired effect:
@Bean
public ObjectMapper jacksonObjectMapper() {
return new ObjectMapper().setPropertyNamingStrategy(
PropertyNamingStrategy.CAMEL_CASE_TO_LOWER_CASE_WITH_UNDERSCORES);
}
Upvotes: 31