Reputation: 365
I need to create a Map from java bean such that the key is prefixed with name of the java bean variable. I am using jackson for this. Example given below:
public class Address{
String city;
String state;
//setters and getters
}
Address address = new Address();
address.setCity("myCity");
address.setState("myState");
I am creating map using following:
ObjectMapper objectMapper = new ObjectMapper();
Map map = objectMapper.convertValue(address, HashMap.class);
Which gives me following output:
{"city":"myCity", "state":"myState"}
I need to add class variable name to the key as shown below:
{"address.city":"myCity", "address.state":"myState"}
How do I achieve that?
Upvotes: 0
Views: 1726
Reputation: 133482
It is possible to customise bean serialization by registering a BeanSerializerModifier. This specifically supports renaming properties by applying a NameTransformer to each BeanPropertyWriter.
@Test
public void prepend_class_name_to_property_keys() throws Exception {
ObjectMapper mapper = new ObjectMapper();
Function<Class<?>, String> classPrefix = clazz -> clazz.getSimpleName().toLowerCase() + ".";
mapper.registerModule(new Module() {
@Override
public String getModuleName() {
return "Example";
}
@Override
public Version version() {
return Version.unknownVersion();
}
@Override
public void setupModule(SetupContext context) {
context.addBeanSerializerModifier(new BeanSerializerModifier() {
@Override
public List<BeanPropertyWriter> changeProperties(SerializationConfig config,
BeanDescription beanDesc, List<BeanPropertyWriter> beanProperties) {
String prefix = classPrefix.apply(beanDesc.getBeanClass());
return beanProperties.stream().map(prop -> prop.rename(new NameTransformer() {
@Override
public String transform(String name) {
return prefix + name;
}
@Override
public String reverse(String transformed) {
return transformed.substring(prefix.length());
}
})).collect(toList());
}
});
}
});
assertThat(mapper.writeValueAsString(new Address("somewhere", "someplace")),
equivalentTo("{ 'address.line1' : 'somewhere', 'address.line2' : 'someplace'}"));
}
public static final class Address {
public final String line1;
public final String line2;
public Address(String line1, String line2) {
this.line1 = line1;
this.line2 = line2;
}
}
Upvotes: 0
Reputation: 3366
If you have jackson-annotations enabled:
public class Address{
@JsonProperty("address.city")
String city;
@JsonProperty("address.state")
String state;
//setters and getters
}
read more about it here: https://github.com/FasterXML/jackson-annotations
Upvotes: 2