为了账号安全,请及时绑定邮箱和手机立即绑定

用于集合类的 Spring Boot 自定义序列化程序

用于集合类的 Spring Boot 自定义序列化程序

至尊宝的传说 2022-08-17 17:17:44
我试图为对象的某个属性实现自定义序列化程序,以便在从 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>> {//....@Overridepublic 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@Beanpublic 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>.classaddSerializer我不想添加自定义序列化程序,因为此类是自动生成的,并且可以添加和删除字段。这应该可以在不修改应用程序代码的情况下实现(如果我有一个自定义序列化程序,您还需要从序列化程序中添加/删除字段(?))。或者,有没有办法只对类使用标准序列化程序,然后手动处理这一个字段。WrapperModelList<>模型类由Spring Boot openapi代码生成器生成,因此我可以将一组非常有限的JSON注释放在模型字段之上(如果有注释方式,请不要犹豫,因为如果支持该特定注释,我可以签入openapi源代码)。但是,如果可能的话,我宁愿使用自定义序列化程序,或者编写一个用于所有内容并且仅自己处理属性的序列化程序。List<Property>WrapperModelStdSerializerList
查看完整描述

1 回答

?
撒科打诨

TA贡献1934条经验 获得超2个赞

米辛

在这种情况下,我们需要使用功能。创建如下界面: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);


查看完整回答
反对 回复 2022-08-17
  • 1 回答
  • 0 关注
  • 95 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信