You can use the same custom serializer but you need to distinguish somehow whether you need to generate property or whole object. Map
is serialized to JSON Object
where Map
keys are converted to JSON Object
properties. To generate property with Jackson
we need to use writeFieldName
method. To distinguish how you would like to use this serialiser in constructor you can provide this information. Example:
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.module.SimpleModule;
import java.io.IOException;
import java.util.Collections;
public class JsonApp {
public static void main(String[] args) throws Exception {
SimpleModule userModule = new SimpleModule();
userModule.addSerializer(User.class, new UserJsonSerializer(false));
userModule.addKeySerializer(User.class, new UserJsonSerializer(true));
ObjectMapper mapper = new ObjectMapper();
mapper.enable(SerializationFeature.INDENT_OUTPUT);
mapper.registerModule(userModule);
User user = new User();
System.out.println(mapper.writeValueAsString(Collections.singletonMap(user, user)));
}
}
class User {
private String firstName = "Tom";
private String lastName = "Smith";
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
}
class UserJsonSerializer extends JsonSerializer<User> {
private final boolean generateKey;
UserJsonSerializer(boolean generateKey) {
this.generateKey = generateKey;
}
@Override
public void serialize(User value, JsonGenerator gen, SerializerProvider serializers)
throws IOException {
if (generateKey) {
serializeAsMapKey(value, gen);
} else {
serializeAsObject(value, gen);
}
}
private void serializeAsMapKey(User value, JsonGenerator gen) throws IOException {
gen.writeFieldName(String.join(",", value.getFirstName(), value.getLastName()));
}
private void serializeAsObject(User value, JsonGenerator gen) throws IOException {
gen.writeStartObject();
gen.writeFieldName("first");
gen.writeString(value.getFirstName());
gen.writeFieldName("last");
gen.writeString(value.getLastName());
gen.writeEndObject();
}
}
Above code prints:
{
"Tom,Smith" : {
"first" : "Tom",
"last" : "Smith"
}
}
If you do not have any common logic you can just create two separate classes: UserJsonSerializer
and UserKeyJsonSerializer
which is an object oriented and clear solution.