In Jackson, custom deserializers allow for extending or modifying the default deserialization behavior. A common need is to access the default deserializer to partially deserialize an object before applying custom logic. However, directly calling deserialize from within a custom deserializer leads to a stack overflow exception.
To resolve this issue, a BeanDeserializerModifier can be implemented and registered with a SimpleModule. This modifier can intervene during the deserializer creation process and inject the default deserializer into our custom deserializer.
The following code demonstrates how to achieve this:
import com.fasterxml.jackson.databind.BeanDescription; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.module.BeanDeserializerModifier; import com.fasterxml.jackson.databind.module.SimpleModule; import com.fasterxml.jackson.databind.util.StdDeserializer; 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); } }
By registering this module with the ObjectMapper, custom deserialization for the User class is enabled, allowing access to the default deserializer for pre-population of the object before applying custom logic.
The above is the detailed content of How Can I Access the Default Deserializer within a Custom Jackson Deserializer?. For more information, please follow other related articles on the PHP Chinese website!