gpt4 book ai didi

java - Jackson 自定义序列化器

转载 作者:行者123 更新时间:2023-11-30 05:27:58 25 4
gpt4 key购买 nike

单个自定义序列化程序可以同时用作键序列化程序和普通对象序列化程序吗?

即有时使用序列化器作为键序列化器来序列化映射键,而其他时间则正常序列化对象。

我遇到了传递给序列化器方法的 JsonGenerator 对象的问题。

当用作键序列化器时,它需要一个字段名称,但正常使用时,它需要值。

最佳答案

您可以使用相同的自定义序列化程序,但您需要以某种方式区分是否需要生成属性或整个对象。 Map 被序列化为 JSON 对象,其中 Map 键被转换为 JSON 对象 属性。要使用 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"
}
}

如果您没有任何通用逻辑,您可以创建两个单独的类:UserJsonSerializerUserKeyJsonSerializer,这是一个面向对象且清晰的解决方案。

关于java - Jackson 自定义序列化器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58178978/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com