可以将单个自定义序列化器用作键序列化器和普通对象序列化器吗?
即有时将序列化程序用作用于序列化地图密钥的密钥序列化程序,而有时则将对象正常序列化。
我在将JsonGenerator对象传递给序列化器方法时遇到问题。
用作键序列化程序时,它需要一个字段名,但是当正常使用时,它需要一个值。
答案 0 :(得分:1)
您可以使用相同的自定义序列化器,但需要以某种方式区分是需要生成属性还是要生成整个对象。 Map
被序列化为JSON Object
,其中Map
键被转换为JSON Object
属性。要使用Jackson
生成属性,我们需要使用writeFieldName
方法。为了区别您想要在构造函数中使用此序列化器的方式,可以提供此信息。示例:
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();
}
}
上面的代码显示:
{
"Tom,Smith" : {
"first" : "Tom",
"last" : "Smith"
}
}
如果没有通用逻辑,则可以创建两个单独的类:UserJsonSerializer
和UserKeyJsonSerializer
,这是一个面向对象的清晰解决方案。