Reputation: 4161
we consume an API with our backend that outputs camelCased properties, map this to POJOs, to apply some business logic and then output it with our API to some apps. The format we want to output is snake_case properties.
This test describes what we want to do:
@Test
public void mappingTest() throws IOException {
String input = "{ \"merchantId\": 23, \"contactName\": \"foobar\" }";
ObjectMapper mapper = new ObjectMapper();
Merchant merch = mapper.readValue(input, Merchant.class);
String output = mapper.writeValueAsString(merch);
String expectedOutput = "{ merchant_id: 23, contact_name: 'foobar' }";
assertEquals("", expectedOutput, output);
}
At the moment the model class looks like this:
@JsonInclude(Include.NON_NULL)
public class Merchant {
private String merchantId;
private String contactName;
public Merchant() {
}
public Merchant(final String merchantId, final String contactName) {
this.merchantId = merchantId;
this.contactName = contactName;
}
@JsonProperty("contact_name")
public String getContactName() {
return contactName;
}
@JsonProperty("contactName")
public void setContactName(final String contactName) {
this.contactName = contactName;
}
@JsonProperty("merchant_id")
public String getMerchantId() {
return merchantId;
}
@JsonProperty("merchantId")
public void setMerchantId(final String merchantId) {
this.merchantId = merchantId;
}
}
It works but I think it's not very elegant since our input is always camelcase and the output is always snakecase. Is there a way to globally set JSON serialization to snakecase and deserialization to camelcase for jackson? (we are using it together with RestTemplate in Spring, if that makes any difference)
Cheers
Upvotes: 3
Views: 139
Reputation: 7157
Use a separately configured ObjectMapper
for your output:
ObjectMapper outputMapper = new ObjectMapper();
outputMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
Using that for writing the output ensures that properties are always written in snake case.
Or if you need to use only a single ObjectMapper
instance, create your own forwarding ProptertyNamingStrategy
:
PropertyNamingStrategy myStrategy = new PropertyNamingStrategy() {
@Override
public String nameForGetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {
return PropertyNamingStrategy.SNAKE_CASE.nameForGetterMethod(config, method, defaultName);
}
@Override
public String nameForSetterMethod(MapperConfig<?> config, AnnotatedMethod method, String defaultName) {
return PropertyNamingStrategy.LOWER_CAMEL_CASE.nameForSetterMethod(config, method, defaultName);
}
};
Upvotes: 0
Reputation: 34920
You can implement and register your own PropertyNamingStrategy
where define different logic for public String nameForGetterMethod(...)
and public String nameForSetterMethod(...)
methods respectively.
Upvotes: 2