package com.fasterxml.jackson.databind.deser; import java.io.IOException; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonToken; import com.fasterxml.jackson.databind.DeserializationConfig; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JsonDeserializer; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.jsontype.TypeIdResolver; /** * This is the class that can be registered (via * {@link DeserializationConfig} object owner by * {@link ObjectMapper}) to get called when a potentially * recoverable problem is encountered during deserialization * process. Handlers can try to resolve the problem, throw * an exception or just skip the content. *
* Default implementations for all methods implemented minimal * "do nothing" functionality, which is roughly equivalent to * not having a registered listener at all. This allows for * only implemented handler methods one is interested in, without * handling other cases. *
* NOTE: it is typically NOT acceptable to simply do nothing, * because this will result in unprocessed tokens being left in * token stream (read via {@link JsonParser}, in case a structured * (JSON Object or JSON Array) value is being pointed to by parser. */ public abstract class DeserializationProblemHandler { /** * Marker value returned by some handler methods to indicate that * they could not handle problem and produce replacement value. * * @since 2.7 */ public final static Object NOT_HANDLED = new Object(); /** * 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: {@link com.fasterxml.jackson.databind.DeserializationFeature#FAIL_ON_UNKNOWN_PROPERTIES})
* takes effect only after handler is called, and only
* if handler did not handle the problem.
*
* @param 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)
* @param p Parser to use for handling problematic content
*
* @return 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.
*/
public boolean handleUnknownProperty(DeserializationContext ctxt, JsonParser p,
JsonDeserializer> deserializer, Object beanOrClass, String propertyName)
throws IOException
{
return false;
}
/**
* 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:
*
null
*
* @since 2.8
*/
public Object handleWeirdKey(DeserializationContext ctxt,
Class> rawKeyType, String keyValue,
String failureMsg)
throws IOException
{
return NOT_HANDLED;
}
/**
* 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:
*targetType
) to use as
* replacement, and continue processing.
* null
)
*
* @since 2.8
*/
public Object handleWeirdStringValue(DeserializationContext ctxt,
Class> targetType, String valueToConvert,
String failureMsg)
throws IOException
{
return NOT_HANDLED;
}
/**
* 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:
*targetType
) to use as
* replacement, and continue processing.
* null
)
*
* @since 2.8
*/
public Object handleWeirdNumberValue(DeserializationContext ctxt,
Class> targetType, Number valueToConvert, String failureMsg)
throws IOException
{
return NOT_HANDLED;
}
/**
* Method called when an embedded (native) value ({@link JsonToken#VALUE_EMBEDDED_OBJECT})
* cannot be converted directly into expected value type (usually POJO).
* Handler may choose to do one of 3 things:
*targetType
) to use as
* replacement, and continue processing.
* null
)
*
* @since 2.9
*/
public Object handleWeirdNativeValue(DeserializationContext ctxt,
JavaType targetType, Object valueToConvert, JsonParser p)
throws IOException
{
return NOT_HANDLED;
}
/**
* Deprecated variant of
* {@link #handleUnexpectedToken(DeserializationContext, JavaType, JsonToken, JsonParser, String)}
*
* @since 2.8
*
* @deprecated Since 2.10
*/
@Deprecated
public Object handleUnexpectedToken(DeserializationContext ctxt,
Class> targetType, JsonToken t, JsonParser p,
String failureMsg)
throws IOException
{
return NOT_HANDLED;
}
/**
* Method that deserializers should call if the first token of the value to
* deserialize is of unexpected type (that is, type of token that deserializer
* cannot handle). This could occur, for example, if a Number deserializer
* encounter {@link JsonToken#START_ARRAY} instead of
* {@link JsonToken#VALUE_NUMBER_INT} or {@link JsonToken#VALUE_NUMBER_FLOAT}.
*targetType
) to use as replacement;
* value may be `null` as well as expected target type.
* null
*
* @since 2.10
*/
public Object handleUnexpectedToken(DeserializationContext ctxt,
JavaType targetType, JsonToken t, JsonParser p,
String failureMsg)
throws IOException
{
// Calling class-version handler for backward compatibility, as of 2.10
return handleUnexpectedToken(ctxt, targetType.getRawClass(), t, p, failureMsg);
}
/**
* Method called when instance creation for a type fails due to an exception.
* Handler may choose to do one of following things:
*targetType
) to use as
* replacement, and continue processing.
* null
to use null as value but not to try further
* processing (in cases where properties would otherwise be bound)
* null
*
* @since 2.8
*/
public Object handleInstantiationProblem(DeserializationContext ctxt,
Class> instClass, Object argument, Throwable t)
throws IOException
{
return NOT_HANDLED;
}
/**
* Method called when instance creation for a type fails due to lack of an
* instantiator. Method is called before actual deserialization from input
* is attempted, so handler may do one of following things:
*targetType
) to use as replacement;
* value may be `null` as well as expected target type.
* null
*
* @since 2.9
*/
public Object handleMissingInstantiator(DeserializationContext ctxt,
Class> instClass, ValueInstantiator valueInsta, JsonParser p,
String msg)
throws IOException
{
// 16-Oct-2016, tatu: Need to delegate to deprecated method from 2.8;
// remove redirect from later versions (post-2.9)
return handleMissingInstantiator(ctxt, instClass, p, msg);
}
/**
* Handler method called if resolution of type id from given String failed
* to produce a subtype; usually because logical id is not mapped to actual
* implementation class.
* Handler may choose to do one of following things:
*