• Now all data be ready for publish, We had made our blog alive now. Haha.



  • These days CCP GFW blocked all the IPs from US and when I switch my IP in google Cloud, the disk data cannot be restore again. I have to restart my blog totally, Now the website is still building…



How do I call the default deserializer from a custom deserializer in Jackson- Stack Overflow

Java PingBook 1 months ago (10-23) 68 0

Question

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 {

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 seems 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 AnnotationIntrospector 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 hold 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.

Answer

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 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);
}
}




Copyright from PingBook Blog, If not specified, they are original. This site uses BY-NC-SAProtocol authenticated.
For reprinting, please indicate the link of the original text:How do I call the default deserializer from a custom deserializer in Jackson- Stack Overflow
LIKE (0)
[1725641479@qq.com]
SHARE (0)
PingBook
Author:
We create, We sharing! Tag every value data your sharing
Submit comments
Cancel comments
emoji picture bold strikethrough center italic check in

Hi,you need to provide your name and email adress!

  • Name (Required)
  • Email (Required)
  • Website