When you annotate a property with @JsonUnwrapped you can add a prefix attribute. For example:
If MyObject has a property "casedProperty", the json key will be "camelcasedProperty" instead of "camelCasedProperty". I found a way to display the json keys the way I wanted. What I did was registering a module with a serializer modifier like this:
The new serializer takes the original serializer as a parameter and most of the time it just delegates to it except for the unwrappingSerializer method, in which it chains the NameTransformer parameter with a new transformer that capitalizes the first character in the name before delegating to the original serializer:
public class MySerializer<T> extends JsonSerializer<T> {
private final JsonSerializer<T> defaultSerializer;
public MySerializer(JsonSerializer<T> defaultSerializer) {
this.defaultSerializer = defaultSerializer;
}
@Override
public void serialize(T t, JsonGenerator gen, SerializerProvider provider) throws IOException {
defaultSerializer.serialize(t, gen, provider);
}
@Override
public JsonSerializer<T> unwrappingSerializer(NameTransformer unwrapper) {
return defaultSerializer.unwrappingSerializer(NameTransformer.chainedTransformer(unwrapper, new CapitalizeTransformer()));
}
private static class CapitalizeTransformer extends NameTransformer {
@Override
public String transform(String name) {
return StringUtils.capitalize(name);
}
@Override
public String reverse(String transformed) {
return StringUtils.uncapitalize(transformed);
}
}
@Override
public JsonSerializer<T> replaceDelegatee(JsonSerializer<?> delegatee) {
return defaultSerializer.replaceDelegatee(delegatee);
}
@Override
public void serializeWithType(T value, JsonGenerator gen, SerializerProvider serializers, TypeSerializer typeSer) throws IOException {
defaultSerializer.serializeWithType(value, gen, serializers, typeSer);
}
@Override
public Class<T> handledType() {
return defaultSerializer.handledType();
}
@Override
public boolean isEmpty(T value) {
return defaultSerializer.isEmpty(value);
}
@Override
public boolean isEmpty(SerializerProvider provider, T value) {
return defaultSerializer.isEmpty(provider, value);
}
@Override
public boolean usesObjectId() {
return defaultSerializer.usesObjectId();
}
@Override
public boolean isUnwrappingSerializer() {
return defaultSerializer.isUnwrappingSerializer();
}
@Override
public JsonSerializer<?> getDelegatee() {
return defaultSerializer.getDelegatee();
}
@Override
public void acceptJsonFormatVisitor(JsonFormatVisitorWrapper visitor, JavaType type) throws JsonMappingException {
defaultSerializer.acceptJsonFormatVisitor(visitor, type);
}
}
My questions are: is there a more straightforward way to achieve what I want? are there any drawbacks in the current approach? Is there a way to provide a custom NameTransformer that does not involve serializer modifiers?
Thank you.