gpt4 book ai didi

java - Collection 类的 Spring Boot 自定义序列化器

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

我试图为我的对象的一个​​属性实现一个自定义序列化器,以便在从 REST Controller 返回它时获得不同的 JSON 结构。

我的限制是我无法更改 REST Controller 或模型类的接口(interface)(因此我无法添加额外的注释等,这可能会使这变得更容易)。我唯一能想到的,使它呈现与模型中描述不同的方式是自定义序列化器,如果有任何更好的方法,请毫不犹豫地告诉我在限制范围内的不同方法。

我的模型看起来像这样:

public class WrapperModel {

// a lot of autogenerated fields

List<Property> properties;

// getters/setters
}

public class Property {

private String name;

private String value;

// getters / setters

}

所以当渲染时看起来像这样:

{   ....   
"properties": [
{"key1": "value1"}, {"key2": "value2"},...
]
}

我想要的是这样的:

{   ....   
"properties": {
"key1": "value1",
"key2": "value2",
...
}
}

序列化器非常简单:

public class PropertyListJSONSerializer extends StdSerializer<List<Property>> {

//....

@Override
public void serialize(List<Property> value, JsonGenerator gen, SerializerProvider provider) throws IOException {
gen.writeStartObject();
for(Property p: value){
gen.writeStringField(p.getName(), p.getValue());
}
gen.writeEndObject();
}

}

现在,当我尝试在 @Configuration 中注册此序列化器时文件:

@Bean
public ObjectMapper objectMapper() {
ObjectMapper mapper = new ObjectMapper();
mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);

SimpleModule module = new SimpleModule();
module.addSerializer(List<Property>.class, new PropertyListJSONSerializer());
mapper.registerModule(module);

return mapper;
}

这不起作用,因为 List<Property>.class不能用于addSerializer因为它是一个模板类。还有其他方法可以添加此序列化器或执行类似操作的方法吗?

我不想为WrapperModel添加自定义序列化器因为此类是自动生成的并且可以添加和删除字段。这应该可以在不修改应用程序代码的情况下实现(如果我有一个自定义序列化程序,您还需要从序列化程序中添加/删除字段(?))。或者有没有一种方法可以只使用该类的标准序列化器并手动处理这个 List<> field 。

模型类是由 Spring Boot openapi 代码生成器生成的,因此我可以在模型字段上放置非常有限的 JSON 注释(如果有注释方式,请随时发布,我可以)检查 openapi 源代码是否支持该特定注释)。但我宁愿使用 List<Property> 的自定义序列化器如果可能的话或者为 WrapperModel 编写一个序列化器使用 StdSerializer对于所有事情,只处理 List我自己的属性(property)。

最佳答案

混入

在这种情况下,我们需要使用MixIn功能。创建如下界面:

interface WrapperModelMixIn {

@JsonSerialize(using = PropertyListJSONSerializer.class)
List<Property> getProperties();
}

并按如下方式注册:

ObjectMapper mapper = new ObjectMapper();
mapper.addMixInAnnotations(WrapperModel.class, WrapperModelMixIn.class);

旧提案

您需要使用Jackson类型,它允许注册通用类型的序列化程序。更改后的序列化程序可能如下所示:

class PropertyListJSONSerializer extends StdSerializer<List<Property>> {

public PropertyListJSONSerializer(JavaType type) {
super(type);
}

@Override
public void serialize(List<Property> value, JsonGenerator gen, SerializerProvider provider)
throws IOException {
gen.writeStartObject();
for (Property p : value) {
gen.writeStringField(p.getName(), p.getValue());
}
gen.writeEndObject();
}
}

您可以按如下方式注册:

ObjectMapper mapper = new ObjectMapper();

CollectionType propertiesListType = mapper.getTypeFactory().constructCollectionType(List.class, Property.class);
SimpleModule module = new SimpleModule();
module.addSerializer(new PropertyListJSONSerializer(propertiesListType));
mapper.registerModule(module);

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

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