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

Jackson自定义序列化程序在Json序列化期间为2个不同的字段显示相同的上下文

魏元白
2023-03-14

我试图基于我的对象类POJO创建一个JSON。对于某些字段,我想使用CustomSerializer,因为我想根据我的需求创建字段。因此,我创建了CustomSerializer.class

CustomSerializer将由我的POJO中的两个不同字段调用,我希望根据哪个字段进行调用来处理不同的事情。对于其中一个字段(extensions),我希望使用fieldname,而对于其他字段(withoutextensions),我不希望在JSON中使用fieldname

我面临的问题是,当调用CustomSerializer时,对于这两个调用,我得到的FieldName,由于无法区分哪个字段当前正在调用CustomSerializer

下面的代码示例将更清楚地说明我所面临的问题:

CustomerPOJO类用于序列化JSON:

@JsonTypeInfo(use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, visible = true, property = "isA")
@JsonInclude(JsonInclude.Include.NON_NULL)
@JsonIgnoreProperties(ignoreUnknown = true)
@Data
@NoArgsConstructor
public class Customer {
    private String isA;
    private String name;

    @JsonSerialize(using = CustomSerializer.class)
    private Map<String, Object> extensions = new HashMap<>();

    private Map<String, Object> withoutExtensions = new HashMap<>();

    @JsonAnyGetter
    @JsonSerialize(using = CustomSerializer.class)
    public Map<String, Object> getWithoutExtensions() {
        return withoutExtensions;
    }

}

下面是我的CustomSerializer,在创建JSON期间,它将被2个字段(extensions和withoutExtensions)调用:

public class CustomSerializer extends JsonSerializer<Map<String, Object>> {

    @Override
    public void serialize(Map<String, Object> value, JsonGenerator gen, SerializerProvider serializers) {
        //I would like to create the outer object for "Extensions" but do not want to create outer object for "WithoutExtensions"
        
         System.out.println(gen.getOutputContext().getCurrentName());

        //In my case for both "Extensions" and "WithoutExtensions" i get the "currentName" as "Extensions" how can I ensure which field is calling this sealizer at
        // present
    }
}
public class Main {
    public static void main(String[] args) throws JsonProcessingException {
        final ObjectMapper objectMapper = new ObjectMapper();
        objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
        final Customer customer = new Customer();

        customer.setName("Jackson");

        Map<String, Object> extensions = new HashMap<>();
        extensions.put("WithObject", "With");
        customer.setExtensions(extensions);

        Map<String, Object> withoutExtensions = new HashMap<>();
        extensions.put("WithoutObject", "Without");
        customer.setWithoutExtensions(withoutExtensions);

        final String eventAsJson = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(customer);
        System.out.println(eventAsJson);
    }
}

正如我们所看到的,当我运行应用程序时,CustomSerializer将在这两种情况下打印扩展。我认为它应该只打印extensions一次,在下一种情况下,它应该提供WithoutExtensions或空字符串。

我只是想知道这是Jackson部分的bug,还是有任何解决方法可以尝试区分哪个字段正在调用我的CustomSerializer

任何帮助都将不胜感激。谢了。

共有1个答案

谷飞星
2023-03-14

优点:

  • 易于实现
  • 易于测试
  • 一个类只做一件事
  • 映射不创建外部对象的序列化程序可以被自定义映射序列化程序(如果可能)替换

缺点:

    null

优点:

  • 可以为每个字段单独配置
  • 可以在需要时共享状态。用户控制创建的实例数。

缺点:

    null
    null
 类似资料:
  • 有没有一种方法可以使用Jackson JSON处理器来执行自定义字段级别的序列化?例如,我想让 注意,age=25被编码为数字,而favoritenumber=123被编码为字符串。Jackson将编组为一个数字。在这种情况下,我希望将favoriteNumber编码为字符串。

  • 问题内容: 有没有一种使用Jackson JSON Processor进行自定义字段级序列化的方法?例如,我想上课 序列化为以下JSON: 请注意,age = 25被编码为 数字, 而favoriteNumber = 123被编码为 string 。开箱即用的杰克逊将集结到一个号码。在这种情况下,我希望将favoriteNumber编码为字符串。 问题答案: 您可以实现自定义序列化器,如下所示:

  • 下面的代码再现了这个问题: 上面的代码不做其他注册“自定义”序列化程序的事情(只是委托回原始序列化程序),但它生成的JSON没有null属性: {“第一个”:“鲍勃”,“最后一个”:“巴克”} 我读过许多看似相关的SO文章,但没有一篇能让我找到解决方案。我尝试在序列化时显式地将映射器设置为,但没有成功。 我唯一的线索是JavaDoc for JsonSerializer中的一条注释: 注意:永远不

  • 问题内容: 是否可能:在类中有一个字段,而在Jackson库中进行序列化/反序列化时却为其使用不同的名称? 例如,我有“ Coordiantes”类。 对于从JSON反序列化,希望具有以下格式: 但是当我序列化对象时,结果应该是这样的: 我试图通过在getter和setter上都应用注释(具有不同的值)来实现此目的: 但我有一个例外: org.codehaus.jackson.map.exc.Un

  • 我的Spring Boot API使用camelCase,但我需要通过我的API将一些请求代理到使用snake_case的第三方API。是否可以将Jackson配置为从snake_case反序列化第三方响应,然后将其序列化回camelCase到我的前端? 所需功能的逐步示例: 示例对象: 我调用我的API API调用第三方 第三方返回 我的API将其反序列化为 我的API序列化对象并返回 现在我使

  • 问题内容: 我知道如何在Jackson中使用自定义序列化程序(通过扩展),但是我希望默认序列化程序可用于除1个字段之外的所有字段,我想使用自定义序列化程序覆盖该字段。 注释不是一种选择,因为我正在序列化一个生成的类(来自Thrift)。 编写自定义杰克逊序列化程序时,如何仅指定要覆盖的某些字段? 更新: 这是我要序列化的类: 上面的类有很多特质,其中大多数使用本机类型。我只想覆盖自定义序列化程序中