我试图为我对象的一个属性实现自定义序列化程序,以便当我从REST控制器返回它时获得不同的JSON结构。
我的约束是我无法更改REST控制器或模型类的接口(因此我无法添加额外的注释等,这可能会使此操作变得更容易)。我唯一能想到的是,使其呈现与模型中描述的不同的是自定义序列化程序,如果有更好的方法,请随时告诉我在约束范围内的另一种方法。>
我的模型如下所示:
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
添加自定义序列化程序,因为该类是自动生成的,并且可以添加和删除字段。这无需修改应用程序代码就可以实现(如果我有一个自定义的序列化程序,则还需要从序列化程序中添加/删除字段(?))。或者,有没有一种方法可以对类使用Standard序列化程序,并手动处理此List<>
字段。
模型类是由Spring Boot openapi代码生成器生成的,因此我可以在模型字段的顶部放置一组非常有限的JSON注释(如果有注释的方法,请不要犹豫地发布)检查openapi源代码(如果支持该特定注释)。但是我更愿意为List<Property>
使用自定义序列化程序,或者为WrapperModel
编写一个序列化程序,为StdSerializer
使用所有内容并且仅处理List
自己财产。
答案 0 :(得分:1)
在这种情况下,我们需要使用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);