当前位置: 首页 > 知识库问答 >
问题:

无字段名的Jackson JSON序列化

孙钱青
2023-03-14
{
  "isA" : "Human",
  "name" : "Batman",
  "age" : "2008",
  "others" : {
    "key1" : "value1",
    "key2" : {
      "key3" : "value3"
    },
    "key5" : {
      "key4" : "One",
      "key4" : "Two"
    }
  }
}

我希望获得以下输出:(我所要做的就是删除map 字段名,但保留其子字段名。)

{
  "isA" : "Human",
  "name" : "Batman",
  "age" : "2008",
  "key1" : "value1",
  "key2" : {
    "key3" : "value3"
  },
  "key5" : {
    "key4" : "One",
    "key4" : "Two"
  }
}

以下是我的human.classPOJO,由ObjectMapper使用:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, visible = true, property = "isA")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@Getter
@Setter
@NoArgsConstructor
@ToString
class Human {
    private String isA;
    private String name;
    private String age;

    @JsonSerialize(using = MyCustomSearlize.class)
    private Map<String, Object> others = new HashMap<>();
}

下面是MAP在搜索过程中使用的我的自定义搜索器:

class MyCustomSearlize extends JsonSerializer<Map<String, Object>> {

    private static final ObjectMapper mapper = new ObjectMapper();

    @Override
    public void serialize(Map<String, Object> value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        gen.writeStartObject();
        recusiveSerializer(value, gen, serializers);
        gen.writeEndObject();
    }

    public void recusiveSerializer(Map<String, Object> value, JsonGenerator gen, SerializerProvider serializers) throws IOException {
        for (Map.Entry<String, Object> extension : value.entrySet()) {
            if (extension.getValue() instanceof Map) {
                //If instance is MAP then call the recursive method
                gen.writeFieldName(extension.getKey());
                gen.writeStartObject();
                recusiveSerializer((Map) extension.getValue(), gen, serializers);
                gen.writeEndObject();
            } else if (extension.getValue() instanceof String) {
                //If instance is String directly add it to the JSON
                gen.writeStringField(extension.getKey(), (String) extension.getValue());
            } else if (extension.getValue() instanceof ArrayList) {
                //If instance if ArrayList then loop over it and add it to the JSON after calling recursive method
                for (Object dupItems : (ArrayList<Object>) extension.getValue()) {
                    if (dupItems instanceof Map) {
                        gen.writeFieldName(extension.getKey());
                        gen.writeStartObject();
                        recusiveSerializer((Map) dupItems, gen, serializers);
                        gen.writeEndObject();
                    } else {
                        gen.writeStringField(extension.getKey(), (String) dupItems);
                    }
                }
            }
        }
    }
}


public class Main {
    public static void main(String[] args) throws JsonProcessingException {

        Human person = new Human();

        person.setName("Batman");
        person.setAge("2008");
        Map<String, Object> others = new HashMap<>();
        others.put("key1", "value1");
        Map<String, Object> complex = new HashMap<>();
        complex.put("key3", "value3");
        others.put("key2", complex);
        Map<String, Object> complex2 = new HashMap<>();
        List<String> dup = new ArrayList<>();
        dup.add("One");
        dup.add("Two");
        complex2.put("key4", dup);
        others.put("key5", complex2);
        person.setOthers(others);

        final ObjectMapper objectMapper = new ObjectMapper();
        SimpleModule simpleModule = new SimpleModule();
        objectMapper.registerModule(simpleModule);
        final String jsonEvent = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(person);
        System.out.println(jsonEvent);
    }
}
    null

是否有一种方法可以使它与@jsonSerialize@jsonanygetter一起使用,因为我不能同时使用这两种方法。

有人能帮忙解决这个问题吗?请指导我适当的文档或变通方法,非常感谢。

共有1个答案

戚飞
2023-03-14

从wiki页面上看,@jsonunwrapped注释应该做您想做的事情。

@jsonunwrapped:property注释用于定义该值在序列化时应该“解包装”(反序列化时再次包装),与POJO结构相比,导致数据结构扁平化。

类的Javadoc也有一个看起来合适的示例。

 类似资料:
  • Form 类中的每个字段不仅负责验证数据,还负责 “清洗” 它 — 将其规范化为一致的格式。 — Django 文档 序列化字段处理基本数据类型和其他数据类型(比如自定义的类)之间的转换。它们还可以对数据进行验证,以及从其父对象中检索和设置值。 注意: 序列化字段都声明在 fields.py 中,但按照惯例,应该使用 from rest_framework import serializers ,

  • 有没有一种方法可以指定不同的序列化/反序列化JSON字段名,而不必显式地写出getter和setter方法,或许可以使用lombok getter和setter? 与此示例类似,下面的代码允许将传入的JSON反序列化为不同的POJO字段名。它还会使POJO字段名序列化为: 但这当然是不成立的。

  • 我正在努力用本地化反序列化世界天气在线API结果。 是否有更好、更简单的解决方案,只为lang对象编写一个自定义反序列化器,并允许GSON自动反序列化其余数据?

  • 问题内容: 我有一个具有以下结构的JSON请求: 现在,res-150p在C#中说了无效的名称,如果我给它起了另一个名字,那么在进行反序列化时我没有得到任何值,res-150p内为空。 编辑: [可序列化] 是包含然后包含的根对象 问题答案: 您必须用属性来修饰属性,以告诉它如果名称不完全匹配该怎么办: 另请参见使用JsonConvert.DeserializeObject将Json反序列化为C#

  • 我有一个错误: 我一直试图避免导致此被序列化的字段,但错误没有得到纠正。我试图把@JsonIgnore放在任何地方,在getter、setter、属性和所有可能的组合中。 谢啦 - 我无法导入com。谷歌。阿彭金。重新包装。组织。科德豪斯。杰克逊。注释JsonIgnoreProperties说,“使用com.google.appengine.repacked可能会导致你的应用程序在没有警告的情况下

  • 问题内容: package main 结构中无名字段的目的是什么? 是否可以像使用命名字段一样访问这些字段? 问题答案: 请参阅“ 在Go中嵌入 ”:您在结构中嵌入了一个匿名字段:通常与嵌入式结构一起使用,而不是像这样的基本类型。该类型没有要显示的“提升字段”。 字段或方法在一个结构匿名字段的被称为 促进 如果是一个合法的选择器,它表示字段或方法。 提升的字段的作用类似于结构的普通字段,只是它们不