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

如何配置杰克逊对象映射器以将 Foo 类型的所有字段反序列化为子类的 Foo 实例?

孔彭祖
2023-03-14

我正在反序列化一个大的json值。深度嵌套在该值中的是一个json对象,如下所示:

{
  "fieldOne": "valueOne",
  "fieldTwo": {
    "innerField": "innerValue"
  }
}

我正在使用JacksonObjectMapper将大的json值反序列化为第3方类。在该第3方类中深度嵌套的是另一个第3方类:

public class DeepThirdPartyClass {
    public String fieldOne;
}

不幸的是,它缺少字段两个属性。我可以创建自己的类来添加缺少的字段:

public class MyClass extends DeepThirdPartyClass {
    public MySubObject fieldTwo;
}

如何配置jackson,以便每当它试图将值反序列化到< code>DeepThirdPartyClass时,它反序列化到< code>MyClass?

共有2个答案

袁奇逸
2023-03-14

我修改了@olga-khylkouskaya的解决方案,以适应我的问题:

@Test
public void newDeserializer() throws Exception {
    ObjectMapper objectMapper = new ObjectMapper();
    SimpleModule module = new SimpleModule("DeepThirdPartyClass subclass override", new Version(1, 0, 0, "FINAL", "com.example", "deep-third-party-class-override"));
    module.addDeserializer(DeepThirdPartyClass.class, new JsonDeserializer<DeepThirdPartyClass>() {
        @Override
        public DeepThirdPartyClass deserialize(JsonParser p, DeserializationContext ctxt) throws IOException, JsonProcessingException {
            return p.readValueAs(MyClass.class);
        }
    });
    objectMapper.registerModule(module);
    objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);

    String json = "{\n" +
            "  \"middle\": {\n" +
            "    \"fieldOne\": \"valueOne\",\n" +
            "    \"fieldTwo\": {\n" +
            "      \"fieldThree\": \"valueThree\"\n" +
            "    }\n" +
            "  }\n" +
            "}\n";

    ThirdPartyClass thirdPartyClass = objectMapper.readValue(json, ThirdPartyClass.class);
}

public class ThirdPartyClass {
    public DeepThirdPartyClass middle;
}

public class InnerClass {
    public String fieldThree;
}
晋涛
2023-03-14

当我必须过滤所有字符串值中的任何不允许的字符时,我也有类似的要求。创建对象映射器:

public class CustomObjectMapper extends ObjectMapper {
    public CustomObjectMapper() {
        super();

        SimpleModule module = new SimpleModule("HTML XSS Serializer", new Version(1, 0, 0, "FINAL", "com.crowdoptic", "web"));
        module.addSerializer(String.class, new JsonHtmlXssSerializer());
        module.addDeserializer(String.class, new JsonHtmlXssDeserializer());

        this.registerModule(module);
    }
}

public class JsonHtmlXssDeserializer extends StdScalarDeserializer<String> {
    private static final Logger LOG = LogManager.getLogger(JsonHtmlXssDeserializer.class);

    public JsonHtmlXssDeserializer() { super(String.class); }

    @Override
    public String deserialize(JsonParser p, DeserializationContext ctxt) throws IOException {
        String value = StringDeserializer.instance.deserialize(p, ctxt);
        LOG.trace("in deserialize for value: " + value);
        String encodedValue = StringEscapeUtils.escapeHtml4(value);
        return encodedValue;
    }
    @Override
    public String deserializeWithType(JsonParser jp, DeserializationContext ctxt, TypeDeserializer typeDeserializer) throws IOException {
        return StringDeserializer.instance.deserializeWithType(jp, ctxt, typeDeserializer);
    }

    @Override
    public boolean isCachable() { return StringDeserializer.instance.isCachable(); }
}

在您的情况下,您可以注册您的类反序列化器,调用对象反序列化器的超级方法。然后,不返回DeepThirdPartyClass,而是创建MyClass的对象,从DeepThirdPartyClass中设置字段一并添加第二个字段。有关实现细节和可用属性,请参见StringDeserializer和其他内容。

如果有帮助,请告诉我。

 类似资料:
  • 问题内容: 我有一个Web服务的结果,该结果返回布尔值或单例映射,例如 布尔结果: 地图结果: 单独地,我可以轻松地映射这两个位置,但是我该如何做呢? 基本上我想将其映射到一个类: 所有所有多态示例都用于基于数据中的属性进行映射,但是在这种情况下,我没有该选项。 编辑 代码的更新部分: 问题答案: 不不不。您不必编写自定义解串器。只需先使用“无类型”映射: 给出“定级” 价值或“定级”价值(采用第

  • 我正在调用一个返回JSON的endpoint,它看起来像这样(在Postman中): 此请求返回的Content-Type头是(与通常的 类来自外部库(编写这个endpoint的人)。无论如何,当我试图通过< code > rest template . exchange()调用这个endpoint时,Jackson都无法将这个JSON反序列化为一个有效的< code>Result类。我正在这样做

  • 问题内容: 我有一个叫做抽象类,然后两个是实现,和。我遇到的问题是,当我将a的其余端点调用到数据库中时,理想情况下,我希望它像将实例传递给REST端点的位置一样。如果不是用一个以上的实现来抽象,那就没问题了,但是由于我有2个,所以我得到了一个错误。 “问题:抽象类型要么需要映射到具体类型,要么具有自定义反序列化器,要么被其他类型信息实例化” 在找到解决方案之后,我找到了一个SO答案,说我可以使用类

  • 我正在尝试使用杰克逊将 JSON 对象反序列化为 Java 对象。json 是由另一位开发人员使用 jackson 库本身创建的,并提供给我。对象图有一个类型为guava的不可变映射的变量,它是一个抽象类。因此,当我尝试反序列化时,杰克逊会给我抛出以下异常。我不是 myJava 类的所有者,因此无法对其进行任何更改,例如通过编写自定义反序列化程序来更改类型或添加注释。 org.codehaus.j

  • 问题内容: 我正在使用Jackson XML映射器将XML反序列化为POJO。XML看起来像 我的课看起来像 我想将电话号码设置为“电话”类别中的号码。我无法更改XML或类的构造方式。我收到无法构造错误的实例,并创建了一个AgencyPhone构造函数 但这没有用。那么如何反序列化嵌套实例。 问题答案: 您可以编写自己的自定义解串器来实现此目的。这是使您入门的代码:

  • 问题内容: 我有以下课程- 我正在使用objectMapper.valueToTree(sections)将其转换为JsonNode。但是,当我打印相同的内容时,我仅从Entity类中看到id和name字段,而从Images列表中看不到任何内容。我是否需要添加任何种类的特殊逻辑或注释以确保同时打印列表。 以下是主要课程- 问题答案: 您需要为Entity#images添加getter和setter