我如何从杰克逊的一个自定义解串器中调用默认的解串器 [英] How do I call the default deserializer from a custom deserializer in Jackson
问题描述
我在杰克逊的自定义反序列化器中遇到问题。我想访问默认的序列化程序来填充我要反序列化的对象。在群体之后,我会做一些自定义的事情,但首先我想用默认的jackson行为反序列化对象。
这是我目前的代码。 / p>
public class UserEventDeserializer扩展了StdDeserializer< User> {
private static final long serialVersionUID = 7923585097068641765L;
public UserEventDeserializer(){
super(User.class);
}
@Override
@Transactional
public User反序列化(JsonParser jp,DeserializationContext ctxt)
抛出IOException,JsonProcessingException {
ObjectCodec oc = jp.getCodec();
JsonNode node = oc.readTree(jp);
User deserializedUser = null;
deserializedUser = super.deserialize(jp,ctxt,new User());
//上一行产生一个异常java.lang.UnsupportedOperationException
//因为没有实现反序列化器。
//我想要一种方法来访问我的User类的默认弹簧解串器。
//我该怎么做?
//特殊逻辑
return deserializedUser;
}
}
我需要的是一种方法初始化默认的反序列化器,这样我就可以在开始我的特殊逻辑之前预先填充我的POJO。
在自定义解串器中调用反序列化时它接口的方法是从无论我如何构建序列化器类,当前上下文都是如此。由于我的POJO中的注释。这显然会导致堆栈溢出异常。我尝试初始化一个beandeserializer,但这个过程非常复杂,我还没有设法找到正确的方法来做到这一点。我也尝试重载注释introspector无济于事,认为它可能会帮助我忽略DeserializerContext中的注释。最后它接缝我可能已经使用JsonDeserializerBuilders取得了一些成功,尽管这需要我做一些魔术来从spring中获取应用程序上下文。我会很感激任何可能导致我得到更清晰的解决方案的事情,例如,如何在不读取JsonDeserializer注释的情况下构建反序列化上下文。
由于StaxMan已经建议您可以通过编写 BeanDeserializerModifier
并通过 SimpleModule
注册。下面的例子应该可以工作:
public class UserEventDeserializer扩展了StdDeserializer< User>实现ResolvableDeserializer
{
private static final long serialVersionUID = 7923585097068641765L;
private final JsonDeserializer<?> defaultDeserializer;
public UserEventDeserializer(JsonDeserializer<?> defaultDeserializer)
{
super(User.class);
this.defaultDeserializer = defaultDeserializer;
}
@Override public User反序列化(JsonParser jp,DeserializationContext ctxt)
抛出IOException异常,JsonProcessingException异常
{
User deserializedUser =(User)defaultDeserializer。反序列化(jp,ctxt);
//特殊逻辑
return deserializedUser;
}
//由于某些原因,在修改BeanDeserializer
时必须实现ResolvableDeserializer //否则反序列化抛出JsonMappingException ??
@Override public void resolve(DeserializationContext ctxt)throws JsonMappingException
{
((ResolvableDeserializer)defaultDeserializer).resolve(ctxt);
$ b public static void main(String [] args)throws JsonParseException,JsonMappingException,IOException
{
SimpleModule module = new SimpleModule();
module.setDeserializerModifier(new BeanDeserializerModifier()
{
@Override public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config,BeanDescription beanDesc,JsonDeserializer<> deserializer)
{
if(beanDesc.getBeanClass()== User.class)
return new UserEventDeserializer(deserializer);
return deserializer;
}
});
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(module);
User user = mapper.readValue(new File(test.json),User.class);
}
}
I have a problem in my custom deserializer in Jackson. I want to access the default serializer to populate the object i am deserializing into. After the population I will do some custom things but first I want to deserialize the object with the default jackson behavior.
This is the code that I have at the moment.
public class UserEventDeserializer extends StdDeserializer<User> {
private static final long serialVersionUID = 7923585097068641765L;
public UserEventDeserializer() {
super(User.class);
}
@Override
@Transactional
public User deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException {
ObjectCodec oc = jp.getCodec();
JsonNode node = oc.readTree(jp);
User deserializedUser = null;
deserializedUser = super.deserialize(jp, ctxt, new User());
// The previous line generates an exception java.lang.UnsupportedOperationException
// Because there is no implementation of the deserializer.
// I want a way to access the default spring deserializer for my User class.
// How can I do that?
//Special logic
return deserializedUser;
}
}
What I need is a way to initialize the default deserializer so that I can pre-populate my POJO before I start my special logic.
When calling deserialize from within the custom deserializer It seams the method is called from the current context no matter how I construct the serializer class. Because of the annotation in my POJO. This causes a Stack Overflow exception for obvious reasons. I have tried initializing a beandeserializer but the process is extremely complex and I haven't managed to find the right way to do it. I have also tried overloading the annotation introspector to no avail, thinking that it might help me ignore the annotation in the DeserializerContext. Finally it seams I might have had some success using JsonDeserializerBuilders although this required me to do some magic stuff to get ahold of the application context from spring. I would appreciate any thing that could lead me to a cleaner solution for example how Can I construct a Deserialization context without reading the JsonDeserializer annotation.
As StaxMan already suggested you can do this by writing a BeanDeserializerModifier
and registering it via SimpleModule
. The following example should work:
public class UserEventDeserializer extends StdDeserializer<User> implements ResolvableDeserializer
{
private static final long serialVersionUID = 7923585097068641765L;
private final JsonDeserializer<?> defaultDeserializer;
public UserEventDeserializer(JsonDeserializer<?> defaultDeserializer)
{
super(User.class);
this.defaultDeserializer = defaultDeserializer;
}
@Override public User deserialize(JsonParser jp, DeserializationContext ctxt)
throws IOException, JsonProcessingException
{
User deserializedUser = (User) defaultDeserializer.deserialize(jp, ctxt);
// Special logic
return deserializedUser;
}
// for some reason you have to implement ResolvableDeserializer when modifying BeanDeserializer
// otherwise deserializing throws JsonMappingException??
@Override public void resolve(DeserializationContext ctxt) throws JsonMappingException
{
((ResolvableDeserializer) defaultDeserializer).resolve(ctxt);
}
public static void main(String[] args) throws JsonParseException, JsonMappingException, IOException
{
SimpleModule module = new SimpleModule();
module.setDeserializerModifier(new BeanDeserializerModifier()
{
@Override public JsonDeserializer<?> modifyDeserializer(DeserializationConfig config, BeanDescription beanDesc, JsonDeserializer<?> deserializer)
{
if (beanDesc.getBeanClass() == User.class)
return new UserEventDeserializer(deserializer);
return deserializer;
}
});
ObjectMapper mapper = new ObjectMapper();
mapper.registerModule(module);
User user = mapper.readValue(new File("test.json"), User.class);
}
}
这篇关于我如何从杰克逊的一个自定义解串器中调用默认的解串器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!