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

如何在自定义反序列化器中使用jackson ObjectMapper?

黄逸清
2023-03-14
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.ObjectCodec;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonNode;
import com.mypackage.MyInterface;
import com.mypackage.MyFailure;
import com.mypackage.MySuccess;

import java.io.IOException;

public class MyDeserializer extends JsonDeserializer<MyInterface> {

    @Override
    public MyInterface deserialize(JsonParser jp, DeserializationContext ctxt)
            throws IOException, JsonProcessingException {
        ObjectCodec codec = jp.getCodec();
        JsonNode node = codec.readTree(jp);
        if (node.has("custom_field")) {
            return codec.treeToValue(node, MyFailure.class);
        } else {
            return codec.treeToValue(node, MySuccess.class);
        }
    }
}
public class MyFailure implements MyInterface {}

public class MySuccess implements MyInterface {}

@JsonDeserialize(using = MyDeserializer.class)
public interface MyInterface {}

我得到了StackOverflowError。了解codec.treeTovalue调用相同的反序列化器。是否有一种方法可以在custome反序列化器中使用codec.treetovalueobjectmapper.readvalue(String,class )

共有1个答案

艾国安
2023-03-14

直接的问题似乎是,@jsondeserialize(using=...)被用于MyInterface的实现以及MyInterface本身:因此出现了无休止的循环。

您可以在每个实现中修复此重写设置:

@JsonDeserialize(using=JsonDeserializer.None.class)
public static class MySuccess implements MyInterface {
}

或者通过使用模块而不是注释来配置反序列化(并从MyInterface中删除注释):

mapper.registerModule(new SimpleModule() {{
    addDeserializer(MyInterface.class, new MyDeserializer());
}});
@Override
public MyInterface convert(JsonNode root, DeserializationContext ctxt) throws IOException {
    java.lang.reflect.Type targetType;
    if (root.has("custom_field")) {
        targetType = MyFailure.class;
    } else {
        targetType = MySuccess.class;
    }
    JavaType jacksonType = ctxt.getTypeFactory().constructType(targetType);
    JsonDeserializer<?> deserializer = ctxt.findRootValueDeserializer(jacksonType);
    JsonParser nodeParser = root.traverse(ctxt.getParser().getCodec());
    nodeParser.nextToken();
    return (MyInterface) deserializer.deserialize(nodeParser, ctxt);
}
 类似资料:
  • 我想反序列化表单中的类: 其中文本是加密的,反序列化应该在重建TestFieldEncryptedMessage实例之前取消对值的加密。 我采用的方法非常类似于:https://github.com/codesqueak/jackson-json-crypto 也就是说,我正在构建一个扩展SimpleModule的模块: 如您所见,设置了两个修饰符:EncryptedSerializerModif

  • 我试图用Jackson库创建复杂类的对象。每个对象都有一个模式,反序列化器需要使用该模式来解释JSON。我的问题是如何向反序列化器提供模式? 反序列化程序扩展了类JSONDeserializer,该类具有无参数构造函数和必须重写的抽象方法反序列化(解析器、上下文)。我想改用另一种方法反序列化(解析器、上下文、值),其中值是部分构造的对象,其中包括模式。也就是说,反序列化方法可以调用value。sc

  • 问题内容: 我有一堂课 我想将下面的JSON数据反序列化到上面的类/对象中 我的想法是在JSON中是一个对象,但我只想获取(在JSON中)在反序列化期间将像在类中那样传递。 如何使用Json.NET实现该目标? 我相信我可以使用CustomJsonConverter完成它。但是我很困惑。docs中的示例仅用于,但不适用。 问题答案: 我只是使用上面在问题中提到的方法解决了我的问题。在我完整的代码下

  • 我想通过扩展默认的反序列化器来创建自己的反序列化器,在其后面设置更多的值: 如您所见,我还想将此DTO母类重用于其他DTO。 我没有找到任何这样的例子。我真的是世界上第一个 反序列化的“AsUsual”(p,ctxt)应该是什么 我应该使用什么motherclass?JsonDeserializer/StdDeserializer/UntypedObjectDeserializer 反序列化程序会

  • 问题内容: 我在使用Gson解析JSON响应时遇到问题。 JSON字串: 我有这两个课程: 但是当使用Gson解析这个时我有一个异常。我知道这是因为响应数组的第一个元素不是对象,而是整数。 所以问题是,我能以某种方式解决它吗? 问题答案: 您必须编写一个 自定义反序列化器 。我会做这样的事情: 首先,您需要包括一个新的类,而不是已有的两个类: 然后,您需要一个自定义解串器,类似于以下内容: 然后,

  • 在一个项目中,我需要用自定义类加载器扩展标准类加载器。这样做的主要动机是在运行时扩展类路径。(有关此问题的解决方案,请参阅:https://stackoverflow.com/a/51584718/231397 ). 通过 工作正常,同时通过反序列化对象 失败,出现异常。原因是调用了标准类加载器,它不知道自定义类加载器。 问:使用自定义类加载器反序列化对象的正确方法是什么?