DeserializationProblemHandler that collects recoverable
problems into a per-call bucket stored in DeserializationContext
attributes.
Design: This handler is completely stateless. The problem collection
bucket is allocated per-call by ObjectReader.readValueCollectingProblems(...)
and stored in per-call context attributes, ensuring thread-safety and call isolation.
Usage: This class is internal infrastructure, registered automatically by
ObjectReader.problemCollectingReader(). Users should not instantiate or
register this handler manually.
Design rationale - Context Attributes vs Handler State:
Problem collection state is stored in DeserializationContext attributes
rather than within this handler for several reasons:
- Thread-safety: The handler instance is shared across all calls to the same ObjectReader. Storing mutable state in the handler would require synchronization and complicate the implementation.
- Call isolation: Each call to
readValueCollectingProblems()needs its own problem bucket. Context attributes are perfect for this - they're created per-call and automatically cleaned up after deserialization. - Immutability: Jackson's config objects (including handlers) are designed to be immutable and reusable. Storing per-call state violates this principle.
- Configuration vs State: The handler stores configuration (max problems limit) while attributes store runtime state (the actual problem list). This separation follows Jackson's design patterns.
The handler itself is stateless - it's just a strategy for handling problems. The actual collection happens in a bucket passed through context attributes.
Recoverable errors handled:
- Unknown properties (
handleUnknownProperty) - skips children - Type coercion failures (
handleWeirdStringValue,handleWeirdNumberValue) - returns defaults - Map key coercion (
handleWeirdKey) - returnsNOT_HANDLED - Instantiation failures (
handleInstantiationProblem) - returns null when safe
Default values: Primitives receive zero/false defaults; reference types
(including boxed primitives) receive null to avoid masking nullability issues.
DoS protection: Collection stops when the configured limit (default 100) is reached, preventing memory/CPU exhaustion attacks.
JSON Pointer: Paths are built from parser context following RFC 6901,
with proper escaping of ~ and / characters via jackson-core's
JsonPointer class.
- Since:
- 3.1
-
Field Summary
FieldsModifier and TypeFieldDescriptionstatic final intDefault maximum number of problems to collect before stopping.Fields inherited from class tools.jackson.databind.deser.DeserializationProblemHandler
NOT_HANDLED -
Constructor Summary
ConstructorsConstructorDescriptionConstructs a handler with the default maximum problem limit.CollectingProblemHandler(int maxProblems) Constructs a handler with a specific maximum problem limit. -
Method Summary
Modifier and TypeMethodDescriptionstatic List<CollectedProblem>Retrieves the problem collection bucket from context attributes.intGets the maximum number of problems this handler will collect.handleInstantiationProblem(DeserializationContext ctxt, Class<?> instClass, Object argument, Throwable t) Method called when instance creation for a type fails due to an exception.booleanhandleUnknownProperty(DeserializationContext ctxt, tools.jackson.core.JsonParser p, ValueDeserializer<?> deserializer, Object beanOrClass, String propertyName) Method called when a JSON Object property with an unrecognized name is encountered.handleWeirdKey(DeserializationContext ctxt, Class<?> rawKeyType, String keyValue, String failureMsg) Method called when a property name from input cannot be converted to a non-Java-String key type (passed asrawKeyType) due to format problem.handleWeirdNumberValue(DeserializationContext ctxt, Class<?> targetType, Number valueToConvert, String failureMsg) Method called when a numeric value (integral or floating-point from input cannot be converted to a non-numeric value type due to specific problem (as opposed to numeric values never being usable).handleWeirdStringValue(DeserializationContext ctxt, Class<?> targetType, String valueToConvert, String failureMsg) Method called when a String value cannot be converted to a non-String value type due to specific problem (as opposed to String values never being usable).Methods inherited from class tools.jackson.databind.deser.DeserializationProblemHandler
handleMissingInstantiator, handleMissingTypeId, handleNullForPrimitives, handleUnexpectedToken, handleUnknownTypeId, handleWeirdNativeValue
-
Field Details
-
DEFAULT_MAX_PROBLEMS
public static final int DEFAULT_MAX_PROBLEMSDefault maximum number of problems to collect before stopping. Prevents memory exhaustion attacks.- See Also:
-
-
Constructor Details
-
CollectingProblemHandler
public CollectingProblemHandler()Constructs a handler with the default maximum problem limit. -
CollectingProblemHandler
public CollectingProblemHandler(int maxProblems) Constructs a handler with a specific maximum problem limit.- Parameters:
maxProblems- Maximum number of problems to collect (must be positive)
-
-
Method Details
-
getMaxProblems
public int getMaxProblems()Gets the maximum number of problems this handler will collect. -
getBucket
Retrieves the problem collection bucket from context attributes.- Returns:
- Problem bucket, or null if not in collecting mode
-
handleUnknownProperty
public boolean handleUnknownProperty(DeserializationContext ctxt, tools.jackson.core.JsonParser p, ValueDeserializer<?> deserializer, Object beanOrClass, String propertyName) throws tools.jackson.core.JacksonException Description copied from class:DeserializationProblemHandlerMethod called when a JSON Object property with an unrecognized name is encountered. Content (supposedly) matching the property are accessible via parser that can be obtained from passed deserialization context. Handler can also choose to skip the content; if so, it MUST return true to indicate it did handle property successfully. Skipping is usually done like so:parser.skipChildren();
Note:
DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) takes effect only after handler is called, and only if handler did not handle the problem.- Overrides:
handleUnknownPropertyin classDeserializationProblemHandlerp- Parser to use for handling problematic contentbeanOrClass- Either bean instance being deserialized (if one has been instantiated so far); or Class that indicates type that will be instantiated (if no instantiation done yet: for example when bean uses non-default constructors)- Returns:
- True if the problem is resolved (and content available used or skipped); false if the handler did not anything and the problem is unresolved. Note that in latter case caller will either throw an exception or explicitly skip the content, depending on configuration.
- Throws:
tools.jackson.core.JacksonException
-
handleWeirdKey
public Object handleWeirdKey(DeserializationContext ctxt, Class<?> rawKeyType, String keyValue, String failureMsg) throws tools.jackson.core.JacksonException Description copied from class:DeserializationProblemHandlerMethod called when a property name from input cannot be converted to a non-Java-String key type (passed asrawKeyType) due to format problem. Handler may choose to do one of 3 things:- Indicate it does not know what to do by returning
DeserializationProblemHandler.NOT_HANDLED - Throw a
IOExceptionto indicate specific fail message (instead of standard exception caller would throw - Return actual key value to use as replacement, and continue processing.
- Overrides:
handleWeirdKeyin classDeserializationProblemHandlerfailureMsg- Message that will be used by caller (by callingDeserializationContext.weirdKeyException(Class, String, String)) to indicate type of failure unless handler produces key to use- Returns:
- Either
DeserializationProblemHandler.NOT_HANDLEDto indicate that handler does not know what to do (and exception may be thrown), or value to use as key (possiblynull - Throws:
tools.jackson.core.JacksonException
- Indicate it does not know what to do by returning
-
handleWeirdStringValue
public Object handleWeirdStringValue(DeserializationContext ctxt, Class<?> targetType, String valueToConvert, String failureMsg) throws tools.jackson.core.JacksonException Description copied from class:DeserializationProblemHandlerMethod called when a String value cannot be converted to a non-String value type due to specific problem (as opposed to String values never being usable). Handler may choose to do one of 3 things:- Indicate it does not know what to do by returning
DeserializationProblemHandler.NOT_HANDLED - Throw a
IOExceptionto indicate specific fail message (instead of standard exception caller would throw - Return actual converted value (of type
targetType) to use as replacement, and continue processing.
- Overrides:
handleWeirdStringValuein classDeserializationProblemHandlerfailureMsg- Message that will be used by caller (by callingDeserializationContext.weirdNumberException(java.lang.Number, java.lang.Class<?>, java.lang.String)) to indicate type of failure unless handler produces key to use- Returns:
- Either
DeserializationProblemHandler.NOT_HANDLEDto indicate that handler does not know what to do (and exception may be thrown), or value to use as (possiblynull) - Throws:
tools.jackson.core.JacksonException
- Indicate it does not know what to do by returning
-
handleWeirdNumberValue
public Object handleWeirdNumberValue(DeserializationContext ctxt, Class<?> targetType, Number valueToConvert, String failureMsg) throws tools.jackson.core.JacksonException Description copied from class:DeserializationProblemHandlerMethod called when a numeric value (integral or floating-point from input cannot be converted to a non-numeric value type due to specific problem (as opposed to numeric values never being usable). Handler may choose to do one of 3 things:- Indicate it does not know what to do by returning
DeserializationProblemHandler.NOT_HANDLED - Throw a
IOExceptionto indicate specific fail message (instead of standard exception caller would throw - Return actual converted value (of type
targetType) to use as replacement, and continue processing.
- Overrides:
handleWeirdNumberValuein classDeserializationProblemHandlerfailureMsg- Message that will be used by caller (by callingDeserializationContext.weirdNumberException(java.lang.Number, java.lang.Class<?>, java.lang.String)) to indicate type of failure unless handler produces key to use- Returns:
- Either
DeserializationProblemHandler.NOT_HANDLEDto indicate that handler does not know what to do (and exception may be thrown), or value to use as (possiblynull) - Throws:
tools.jackson.core.JacksonException
- Indicate it does not know what to do by returning
-
handleInstantiationProblem
public Object handleInstantiationProblem(DeserializationContext ctxt, Class<?> instClass, Object argument, Throwable t) throws tools.jackson.core.JacksonException Description copied from class:DeserializationProblemHandlerMethod called when instance creation for a type fails due to an exception. Handler may choose to do one of following things:- Indicate it does not know what to do by returning
DeserializationProblemHandler.NOT_HANDLED - Throw a
IOExceptionto indicate specific fail message (instead of standard exception caller would throw - Return actual instantiated value (of type
targetType) to use as replacement, and continue processing. - Return
nullto use null as value but not to try further processing (in cases where properties would otherwise be bound)
- Overrides:
handleInstantiationProblemin classDeserializationProblemHandlerinstClass- Type that was to be instantiatedargument- (optional) Additional argument that was passed to creator, if anyt- Exception that caused instantiation failure- Returns:
- Either
DeserializationProblemHandler.NOT_HANDLEDto indicate that handler does not know what to do (and exception may be thrown), or value to use (possiblynull - Throws:
tools.jackson.core.JacksonException
- Indicate it does not know what to do by returning
-