Class CollectingProblemHandler

java.lang.Object
tools.jackson.databind.deser.DeserializationProblemHandler
tools.jackson.databind.deser.CollectingProblemHandler

public class CollectingProblemHandler extends DeserializationProblemHandler
Stateless 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:

  1. 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.
  2. 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.
  3. Immutability: Jackson's config objects (including handlers) are designed to be immutable and reusable. Storing per-call state violates this principle.
  4. 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:

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 Details

    • DEFAULT_MAX_PROBLEMS

      public static final int DEFAULT_MAX_PROBLEMS
      Default 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

      public static List<CollectedProblem> getBucket(DeserializationContext ctxt)
      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: DeserializationProblemHandler
      Method 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:
      handleUnknownProperty in class DeserializationProblemHandler
      p - Parser to use for handling problematic content
      beanOrClass - 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: DeserializationProblemHandler
      Method called when a property name from input cannot be converted to a non-Java-String key type (passed as rawKeyType) 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 IOException to indicate specific fail message (instead of standard exception caller would throw
      • Return actual key value to use as replacement, and continue processing.
      Overrides:
      handleWeirdKey in class DeserializationProblemHandler
      failureMsg - Message that will be used by caller (by calling DeserializationContext.weirdKeyException(Class, String, String)) to indicate type of failure unless handler produces key to use
      Returns:
      Either DeserializationProblemHandler.NOT_HANDLED to indicate that handler does not know what to do (and exception may be thrown), or value to use as key (possibly null
      Throws:
      tools.jackson.core.JacksonException
    • handleWeirdStringValue

      public Object handleWeirdStringValue(DeserializationContext ctxt, Class<?> targetType, String valueToConvert, String failureMsg) throws tools.jackson.core.JacksonException
      Description copied from class: DeserializationProblemHandler
      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). Handler may choose to do one of 3 things:
      • Indicate it does not know what to do by returning DeserializationProblemHandler.NOT_HANDLED
      • Throw a IOException to 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:
      handleWeirdStringValue in class DeserializationProblemHandler
      failureMsg - Message that will be used by caller (by calling DeserializationContext.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_HANDLED to indicate that handler does not know what to do (and exception may be thrown), or value to use as (possibly null)
      Throws:
      tools.jackson.core.JacksonException
    • handleWeirdNumberValue

      public Object handleWeirdNumberValue(DeserializationContext ctxt, Class<?> targetType, Number valueToConvert, String failureMsg) throws tools.jackson.core.JacksonException
      Description copied from class: DeserializationProblemHandler
      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). Handler may choose to do one of 3 things:
      • Indicate it does not know what to do by returning DeserializationProblemHandler.NOT_HANDLED
      • Throw a IOException to 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:
      handleWeirdNumberValue in class DeserializationProblemHandler
      failureMsg - Message that will be used by caller (by calling DeserializationContext.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_HANDLED to indicate that handler does not know what to do (and exception may be thrown), or value to use as (possibly null)
      Throws:
      tools.jackson.core.JacksonException
    • handleInstantiationProblem

      public Object handleInstantiationProblem(DeserializationContext ctxt, Class<?> instClass, Object argument, Throwable t) throws tools.jackson.core.JacksonException
      Description copied from class: DeserializationProblemHandler
      Method 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 IOException to 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 null to use null as value but not to try further processing (in cases where properties would otherwise be bound)
      Overrides:
      handleInstantiationProblem in class DeserializationProblemHandler
      instClass - Type that was to be instantiated
      argument - (optional) Additional argument that was passed to creator, if any
      t - Exception that caused instantiation failure
      Returns:
      Either DeserializationProblemHandler.NOT_HANDLED to indicate that handler does not know what to do (and exception may be thrown), or value to use (possibly null
      Throws:
      tools.jackson.core.JacksonException