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

Jackson静态编程语言中泛型类型的自定义反序列化/Java

逑和蔼
2023-03-14

有了这个数据模型...

TestClass.kt

data class TestClass (val bar: Optional<Double>?)

我的目标是反序列化以下json值:

{"foo": 3.5}  --> foo = 3.5
{"foo": null} --> foo = Optional.empty() // This is currently my problem. foo is null and I can't seem to fix it
{}            --> foo = null

我在这里看到了解决方案并尝试了这个,但是我的“反序列化”方法中的断点似乎永远不会命中。

选项Deserializer.java

import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.databind.*;
import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
import java.io.IOException;
import java.util.Optional;

public class OptionalDeserializer extends JsonDeserializer<Optional<?>> implements ContextualDeserializer {
    private JavaType valueType;

    @Override
    public JsonDeserializer<?> createContextual(DeserializationContext context, BeanProperty property) {
        this.valueType = property.getType().containedType(0);
        return this;
    }

    @Override
    public Optional<?> deserialize(final JsonParser parser, final DeserializationContext context) throws IOException {
        final JsonNode node = parser.getCodec().readTree(parser);

        return node.isNull()
                ? Optional.empty()
                : Optional.of(context.readValue(parser, valueType));
    }

}

TestDeserialization.kt

fun main(): {
    val objectMapper = ObjectMapper().registerModule(KotlinModule())

    val module = SimpleModule()
    module.addDeserializer(Optional::class.java, OptionalDeserializer())
    objectMapper.registerModule(module)

    objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL)

    objectMapper.configure(JsonGenerator.Feature.WRITE_BIGDECIMAL_AS_PLAIN, true)
    objectMapper.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true)
    objectMapper.nodeFactory = JsonNodeFactory.withExactBigDecimals(true)

    val inputJson = """{"foo" : null}"""

    val expectedObject = TestClass(foo = Optional.empty())

    val actualObject = objectMapper.readValue(inputJson, TestClassBravo::class.java)

    assertEquals(expectedObject, actualObject)
}

建筑gradle(用于版本信息)

compile 'com.fasterxml.jackson.core:jackson-databind:2.9.8'
compile 'com.fasterxml.jackson.module:jackson-module-kotlin:2.9.8'

共有1个答案

卢健
2023-03-14

有两种方法可以解决这个问题。

>

  • 不使用自定义序列化程序更容易,而依赖jackson默认Jdk8Module(请参阅此处)

    如果需要自定义反序列化器,则需要指定null访问模式,否则将不对值调用反序列化器:

    2的代码:

    // In OptionalDeserializer
    
    @Override
    public AccessPattern getNullAccessPattern() {
        return AccessPattern.CONSTANT;
    }
    

  •  类似资料:
    • 问题内容: 我正在尝试制作一个使用Jackson来反序列化POJO的类。 看起来像这样… 我对此实施有2个问题。 首先是我将类类型传递给方法,以便对象映射器知道应反序列化的类型。有使用泛型的更好方法吗? 同样在get方法中,我将一个从objectMapper返回的对象强制转换为T。这看起来特别讨厌,因为我必须在此处强制转换T,然后还必须从调用它的方法中强制转换对象类型。 我在该项目中使用了Robo

    • 想象一下以下场景: 我想为Foo编写一个自定义的Jackson反序列化程序。为了做到这一点(例如,为了反序列化具有Foo的类 如何编写这样的反序列化程序?这应该是可能的,因为Jackson是通过键入集合和地图来实现的。 澄清: 似乎有两个部分可以解决这个问题: 1)获取内声明的属性类型并使用它来反序列化

    • 问题内容: 我有一个json字符串,应该将其反序列化为以下类 我该怎么做?这是通常的方式 但是我怎么提到T代表什么呢? 问题答案: 你需要为使用的每种通用类型创建一个对象,并将其用于反序列化。例如

    • 我有一个json字符串,我应该将其反序列化为以下类 我怎么做?这是通常的方式 但我怎么说T代表什么呢?

    • 我看过jackson反序列化@JsonTypeInfo的一个例子,那就是: 我试过了,效果很好。现在的问题是,在示例类中,Cat和Dog是从Animal中引用的,我想避免这种情况。有没有一种方法可以将类型绑定从类动物中移除,并且仍然进行反序列化工作?谢谢