* mapper.configOverride(java.util.Date.class)
* .setFormat(JsonFormat.Value.forPattern("yyyy-MM-dd"));
*
* to change the default format to use for properties of type
* {@link java.util.Date} (possibly further overridden by per-property
* annotations)
*
* @since 2.8
*/
public MutableConfigOverride configOverride(Class> type) {
return _configOverrides.findOrCreateOverride(type);
}
/*
/**********************************************************
/* Configuration, basic type handling
/**********************************************************
*/
/**
* Accessor for getting currently configured {@link TypeFactory} instance.
*/
public TypeFactory getTypeFactory() {
return _typeFactory;
}
/**
* Method that can be used to override {@link TypeFactory} instance
* used by this mapper.
*
* Note: will also set {@link TypeFactory} that deserialization and
* serialization config objects use.
*/
public ObjectMapper setTypeFactory(TypeFactory f)
{
_typeFactory = f;
_deserializationConfig = _deserializationConfig.with(f);
_serializationConfig = _serializationConfig.with(f);
return this;
}
/**
* Convenience method for constructing {@link JavaType} out of given
* type (typically java.lang.Class
), but without explicit
* context.
*/
public JavaType constructType(Type t) {
return _typeFactory.constructType(t);
}
/*
/**********************************************************
/* Configuration, deserialization
/**********************************************************
*/
/**
* Method that can be used to get hold of {@link JsonNodeFactory}
* that this mapper will use when directly constructing
* root {@link JsonNode} instances for Trees.
*
* Note: this is just a shortcut for calling
*
* getDeserializationConfig().getNodeFactory()
*
*/
public JsonNodeFactory getNodeFactory() {
return _deserializationConfig.getNodeFactory();
}
/**
* Method for specifying {@link JsonNodeFactory} to use for
* constructing root level tree nodes (via method
* {@link #createObjectNode}
*/
public ObjectMapper setNodeFactory(JsonNodeFactory f) {
_deserializationConfig = _deserializationConfig.with(f);
return this;
}
/**
* Method for adding specified {@link DeserializationProblemHandler}
* to be used for handling specific problems during deserialization.
*/
public ObjectMapper addHandler(DeserializationProblemHandler h) {
_deserializationConfig = _deserializationConfig.withHandler(h);
return this;
}
/**
* Method for removing all registered {@link DeserializationProblemHandler}s
* instances from this mapper.
*/
public ObjectMapper clearProblemHandlers() {
_deserializationConfig = _deserializationConfig.withNoProblemHandlers();
return this;
}
/**
* Method that allows overriding of the underlying {@link DeserializationConfig}
* object.
* It is added as a fallback method that may be used if no other configuration
* modifier method works: it should not be used if there are alternatives,
* and its use is generally discouraged.
*
* NOTE : only use this method if you know what you are doing -- it allows
* by-passing some of checks applied to other configuration methods.
* Also keep in mind that as with all configuration of {@link ObjectMapper},
* this is only thread-safe if done before calling any deserialization methods.
*
* @since 2.4
*/
public ObjectMapper setConfig(DeserializationConfig config) {
_deserializationConfig = config;
return this;
}
/*
/**********************************************************
/* Configuration, serialization
/**********************************************************
*/
/**
* @deprecated Since 2.6, use {@link #setFilterProvider} instead (allows chaining)
*/
@Deprecated
public void setFilters(FilterProvider filterProvider) {
_serializationConfig = _serializationConfig.withFilters(filterProvider);
}
/**
* Method for configuring this mapper to use specified {@link FilterProvider} for
* mapping Filter Ids to actual filter instances.
*
* Note that usually it is better to use method {@link #writer(FilterProvider)};
* however, sometimes
* this method is more convenient. For example, some frameworks only allow configuring
* of ObjectMapper instances and not {@link ObjectWriter}s.
*
* @since 2.6
*/
public ObjectMapper setFilterProvider(FilterProvider filterProvider) {
_serializationConfig = _serializationConfig.withFilters(filterProvider);
return this;
}
/**
* Method that will configure default {@link Base64Variant} that
* byte[]
serializers and deserializers will use.
*
* @param v Base64 variant to use
*
* @return This mapper, for convenience to allow chaining
*
* @since 2.1
*/
public ObjectMapper setBase64Variant(Base64Variant v) {
_serializationConfig = _serializationConfig.with(v);
_deserializationConfig = _deserializationConfig.with(v);
return this;
}
/**
* Method that allows overriding of the underlying {@link SerializationConfig}
* object, which contains serialization-specific configuration settings.
* It is added as a fallback method that may be used if no other configuration
* modifier method works: it should not be used if there are alternatives,
* and its use is generally discouraged.
*
* NOTE : only use this method if you know what you are doing -- it allows
* by-passing some of checks applied to other configuration methods.
* Also keep in mind that as with all configuration of {@link ObjectMapper},
* this is only thread-safe if done before calling any serialization methods.
*
* @since 2.4
*/
public ObjectMapper setConfig(SerializationConfig config) {
_serializationConfig = config;
return this;
}
/*
/**********************************************************
/* Configuration, other
/**********************************************************
*/
/**
* Method that can be used to get hold of {@link JsonFactory} that this
* mapper uses if it needs to construct {@link JsonParser}s
* and/or {@link JsonGenerator}s.
*
* WARNING: note that all {@link ObjectReader} and {@link ObjectWriter}
* instances created by this mapper usually share the same configured
* {@link JsonFactory}, so changes to its configuration will "leak".
* To avoid such observed changes you should always use "with()" and
* "without()" method of {@link ObjectReader} and {@link ObjectWriter}
* for changing {@link com.pdd.pop.ext.fasterxml.jackson.core.JsonParser.Feature}
* and {@link com.pdd.pop.ext.fasterxml.jackson.core.JsonGenerator.Feature}
* settings to use on per-call basis.
*
* @return {@link JsonFactory} that this mapper uses when it needs to
* construct Json parser and generators
*/
@Override
public JsonFactory getFactory() { return _jsonFactory; }
/**
* @deprecated Since 2.1: Use {@link #getFactory} instead
*/
@Deprecated
@Override
public JsonFactory getJsonFactory() { return getFactory(); }
/**
* Method for configuring the default {@link DateFormat} to use when serializing time
* values as Strings, and deserializing from JSON Strings.
* This is preferably to directly modifying {@link SerializationConfig} and
* {@link DeserializationConfig} instances.
* If you need per-request configuration, use {@link #writer(DateFormat)} to
* create properly configured {@link ObjectWriter} and use that; this because
* {@link ObjectWriter}s are thread-safe whereas ObjectMapper itself is only
* thread-safe when configuring methods (such as this one) are NOT called.
*/
public ObjectMapper setDateFormat(DateFormat dateFormat)
{
_deserializationConfig = _deserializationConfig.with(dateFormat);
_serializationConfig = _serializationConfig.with(dateFormat);
return this;
}
/**
* @since 2.5
*/
public DateFormat getDateFormat() {
// arbitrary choice but let's do:
return _serializationConfig.getDateFormat();
}
/**
* Method for configuring {@link HandlerInstantiator} to use for creating
* instances of handlers (such as serializers, deserializers, type and type
* id resolvers), given a class.
*
* @param hi Instantiator to use; if null, use the default implementation
*/
public Object setHandlerInstantiator(HandlerInstantiator hi)
{
_deserializationConfig = _deserializationConfig.with(hi);
_serializationConfig = _serializationConfig.with(hi);
return this;
}
/**
* Method for configuring {@link InjectableValues} which used to find
* values to inject.
*/
public ObjectMapper setInjectableValues(InjectableValues injectableValues) {
_injectableValues = injectableValues;
return this;
}
/**
* @since 2.6
*/
public InjectableValues getInjectableValues() {
return _injectableValues;
}
/**
* Method for overriding default locale to use for formatting.
* Default value used is {@link Locale#getDefault()}.
*/
public ObjectMapper setLocale(Locale l) {
_deserializationConfig = _deserializationConfig.with(l);
_serializationConfig = _serializationConfig.with(l);
return this;
}
/**
* Method for overriding default TimeZone to use for formatting.
* Default value used is UTC (NOT default TimeZone of JVM).
*/
public ObjectMapper setTimeZone(TimeZone tz) {
_deserializationConfig = _deserializationConfig.with(tz);
_serializationConfig = _serializationConfig.with(tz);
return this;
}
/*
/**********************************************************
/* Configuration, simple features: MapperFeature
/**********************************************************
*/
/**
* Method for checking whether given {@link MapperFeature} is enabled.
*/
public boolean isEnabled(MapperFeature f) {
// ok to use either one, should be kept in sync
return _serializationConfig.isEnabled(f);
}
/**
* Method for changing state of an on/off mapper feature for
* this mapper instance.
*/
public ObjectMapper configure(MapperFeature f, boolean state) {
_serializationConfig = state ?
_serializationConfig.with(f) : _serializationConfig.without(f);
_deserializationConfig = state ?
_deserializationConfig.with(f) : _deserializationConfig.without(f);
return this;
}
/**
* Method for enabling specified {@link MapperConfig} features.
* Modifies and returns this instance; no new object is created.
*/
public ObjectMapper enable(MapperFeature... f) {
_deserializationConfig = _deserializationConfig.with(f);
_serializationConfig = _serializationConfig.with(f);
return this;
}
/**
* Method for enabling specified {@link DeserializationConfig} features.
* Modifies and returns this instance; no new object is created.
*/
public ObjectMapper disable(MapperFeature... f) {
_deserializationConfig = _deserializationConfig.without(f);
_serializationConfig = _serializationConfig.without(f);
return this;
}
/*
/**********************************************************
/* Configuration, simple features: SerializationFeature
/**********************************************************
*/
/**
* Method for checking whether given serialization-specific
* feature is enabled.
*/
public boolean isEnabled(SerializationFeature f) {
return _serializationConfig.isEnabled(f);
}
/**
* Method for changing state of an on/off serialization feature for
* this object mapper.
*/
public ObjectMapper configure(SerializationFeature f, boolean state) {
_serializationConfig = state ?
_serializationConfig.with(f) : _serializationConfig.without(f);
return this;
}
/**
* Method for enabling specified {@link DeserializationConfig} feature.
* Modifies and returns this instance; no new object is created.
*/
public ObjectMapper enable(SerializationFeature f) {
_serializationConfig = _serializationConfig.with(f);
return this;
}
/**
* Method for enabling specified {@link DeserializationConfig} features.
* Modifies and returns this instance; no new object is created.
*/
public ObjectMapper enable(SerializationFeature first,
SerializationFeature... f) {
_serializationConfig = _serializationConfig.with(first, f);
return this;
}
/**
* Method for enabling specified {@link DeserializationConfig} features.
* Modifies and returns this instance; no new object is created.
*/
public ObjectMapper disable(SerializationFeature f) {
_serializationConfig = _serializationConfig.without(f);
return this;
}
/**
* Method for enabling specified {@link DeserializationConfig} features.
* Modifies and returns this instance; no new object is created.
*/
public ObjectMapper disable(SerializationFeature first,
SerializationFeature... f) {
_serializationConfig = _serializationConfig.without(first, f);
return this;
}
/*
/**********************************************************
/* Configuration, simple features: DeserializationFeature
/**********************************************************
*/
/**
* Method for checking whether given deserialization-specific
* feature is enabled.
*/
public boolean isEnabled(DeserializationFeature f) {
return _deserializationConfig.isEnabled(f);
}
/**
* Method for changing state of an on/off deserialization feature for
* this object mapper.
*/
public ObjectMapper configure(DeserializationFeature f, boolean state) {
_deserializationConfig = state ?
_deserializationConfig.with(f) : _deserializationConfig.without(f);
return this;
}
/**
* Method for enabling specified {@link DeserializationConfig} features.
* Modifies and returns this instance; no new object is created.
*/
public ObjectMapper enable(DeserializationFeature feature) {
_deserializationConfig = _deserializationConfig.with(feature);
return this;
}
/**
* Method for enabling specified {@link DeserializationConfig} features.
* Modifies and returns this instance; no new object is created.
*/
public ObjectMapper enable(DeserializationFeature first,
DeserializationFeature... f) {
_deserializationConfig = _deserializationConfig.with(first, f);
return this;
}
/**
* Method for enabling specified {@link DeserializationConfig} features.
* Modifies and returns this instance; no new object is created.
*/
public ObjectMapper disable(DeserializationFeature feature) {
_deserializationConfig = _deserializationConfig.without(feature);
return this;
}
/**
* Method for enabling specified {@link DeserializationConfig} features.
* Modifies and returns this instance; no new object is created.
*/
public ObjectMapper disable(DeserializationFeature first,
DeserializationFeature... f) {
_deserializationConfig = _deserializationConfig.without(first, f);
return this;
}
/*
/**********************************************************
/* Configuration, simple features: JsonParser.Feature
/**********************************************************
*/
public boolean isEnabled(JsonParser.Feature f) {
return _deserializationConfig.isEnabled(f, _jsonFactory);
}
/**
* Method for changing state of specified {@link com.pdd.pop.ext.fasterxml.jackson.core.JsonParser.Feature}s
* for parser instances this object mapper creates.
*
* Note that this is equivalent to directly calling same method
* on {@link #getFactory}.
*
* WARNING: since this method directly modifies state of underlying {@link JsonFactory},
* it will change observed configuration by {@link ObjectReader}s as well -- to avoid
* this, use {@link ObjectReader#with(JsonParser.Feature)} instead.
*/
public ObjectMapper configure(JsonParser.Feature f, boolean state) {
_jsonFactory.configure(f, state);
return this;
}
/**
* Method for enabling specified {@link com.pdd.pop.ext.fasterxml.jackson.core.JsonParser.Feature}s
* for parser instances this object mapper creates.
*
* Note that this is equivalent to directly calling same method on {@link #getFactory}.
*
* WARNING: since this method directly modifies state of underlying {@link JsonFactory},
* it will change observed configuration by {@link ObjectReader}s as well -- to avoid
* this, use {@link ObjectReader#with(JsonParser.Feature)} instead.
*
* @since 2.5
*/
public ObjectMapper enable(JsonParser.Feature... features) {
for (JsonParser.Feature f : features) {
_jsonFactory.enable(f);
}
return this;
}
/**
* Method for disabling specified {@link com.pdd.pop.ext.fasterxml.jackson.core.JsonParser.Feature}s
* for parser instances this object mapper creates.
*
* Note that this is equivalent to directly calling same method on {@link #getFactory}.
*
* WARNING: since this method directly modifies state of underlying {@link JsonFactory},
* it will change observed configuration by {@link ObjectReader}s as well -- to avoid
* this, use {@link ObjectReader#without(JsonParser.Feature)} instead.
*
* @since 2.5
*/
public ObjectMapper disable(JsonParser.Feature... features) {
for (JsonParser.Feature f : features) {
_jsonFactory.disable(f);
}
return this;
}
/*
/**********************************************************
/* Configuration, simple features: JsonGenerator.Feature
/**********************************************************
*/
public boolean isEnabled(JsonGenerator.Feature f) {
return _serializationConfig.isEnabled(f, _jsonFactory);
}
/**
* Method for changing state of an on/off {@link JsonGenerator} feature for
* generator instances this object mapper creates.
*
* Note that this is equivalent to directly calling same method
* on {@link #getFactory}.
*
* WARNING: since this method directly modifies state of underlying {@link JsonFactory},
* it will change observed configuration by {@link ObjectWriter}s as well -- to avoid
* this, use {@link ObjectWriter#with(JsonGenerator.Feature)} instead.
*/
public ObjectMapper configure(JsonGenerator.Feature f, boolean state) {
_jsonFactory.configure(f, state);
return this;
}
/**
* Method for enabling specified {@link com.pdd.pop.ext.fasterxml.jackson.core.JsonGenerator.Feature}s
* for parser instances this object mapper creates.
*
* Note that this is equivalent to directly calling same method on {@link #getFactory}.
*
* WARNING: since this method directly modifies state of underlying {@link JsonFactory},
* it will change observed configuration by {@link ObjectWriter}s as well -- to avoid
* this, use {@link ObjectWriter#with(JsonGenerator.Feature)} instead.
*
* @since 2.5
*/
public ObjectMapper enable(JsonGenerator.Feature... features) {
for (JsonGenerator.Feature f : features) {
_jsonFactory.enable(f);
}
return this;
}
/**
* Method for disabling specified {@link com.pdd.pop.ext.fasterxml.jackson.core.JsonGenerator.Feature}s
* for parser instances this object mapper creates.
*
* Note that this is equivalent to directly calling same method on {@link #getFactory}.
*
* WARNING: since this method directly modifies state of underlying {@link JsonFactory},
* it will change observed configuration by {@link ObjectWriter}s as well -- to avoid
* this, use {@link ObjectWriter#without(JsonGenerator.Feature)} instead.
*
* @since 2.5
*/
public ObjectMapper disable(JsonGenerator.Feature... features) {
for (JsonGenerator.Feature f : features) {
_jsonFactory.disable(f);
}
return this;
}
/*
/**********************************************************
/* Configuration, simple features: JsonFactory.Feature
/**********************************************************
*/
/**
* Convenience method, equivalent to:
*
* getJsonFactory().isEnabled(f);
*
*/
public boolean isEnabled(JsonFactory.Feature f) {
return _jsonFactory.isEnabled(f);
}
/*
/**********************************************************
/* Public API (from ObjectCodec): deserialization
/* (mapping from JSON to Java types);
/* main methods
/**********************************************************
*/
/**
* Method to deserialize JSON content into a non-container
* type (it can be an array type, however): typically a bean, array
* or a wrapper type (like {@link java.lang.Boolean}).
*
* Note: this method should NOT be used if the result type is a
* container ({@link java.util.Collection} or {@link java.util.Map}.
* The reason is that due to type erasure, key and value types
* cannot be introspected when using this method.
*
* @throws IOException if a low-level I/O problem (unexpected end-of-input,
* network error) occurs (passed through as-is without additional wrapping -- note
* that this is one case where {@link DeserializationFeature#WRAP_EXCEPTIONS}
* does NOT result in wrapping of exception even if enabled)
* @throws JsonParseException if underlying input contains invalid content
* of type {@link JsonParser} supports (JSON for default case)
* @throws JsonMappingException if the input JSON structure does not match structure
* expected for result type (or has other mismatch issues)
*/
@Override
@SuppressWarnings("unchecked")
public T readValue(JsonParser p, Class valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readValue(getDeserializationConfig(), p, _typeFactory.constructType(valueType));
}
/**
* Method to deserialize JSON content into a Java type, reference
* to which is passed as argument. Type is passed using so-called
* "super type token" (see )
* and specifically needs to be used if the root type is a
* parameterized (generic) container type.
*
* @throws IOException if a low-level I/O problem (unexpected end-of-input,
* network error) occurs (passed through as-is without additional wrapping -- note
* that this is one case where {@link DeserializationFeature#WRAP_EXCEPTIONS}
* does NOT result in wrapping of exception even if enabled)
* @throws JsonParseException if underlying input contains invalid content
* of type {@link JsonParser} supports (JSON for default case)
* @throws JsonMappingException if the input JSON structure does not match structure
* expected for result type (or has other mismatch issues)
*/
@Override
@SuppressWarnings("unchecked")
public T readValue(JsonParser p, TypeReference> valueTypeRef)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readValue(getDeserializationConfig(), p, _typeFactory.constructType(valueTypeRef));
}
/**
* Method to deserialize JSON content into a Java type, reference
* to which is passed as argument. Type is passed using
* Jackson specific type; instance of which can be constructed using
* {@link TypeFactory}.
*
* @throws IOException if a low-level I/O problem (unexpected end-of-input,
* network error) occurs (passed through as-is without additional wrapping -- note
* that this is one case where {@link DeserializationFeature#WRAP_EXCEPTIONS}
* does NOT result in wrapping of exception even if enabled)
* @throws JsonParseException if underlying input contains invalid content
* of type {@link JsonParser} supports (JSON for default case)
* @throws JsonMappingException if the input JSON structure does not match structure
* expected for result type (or has other mismatch issues)
*/
@Override
@SuppressWarnings("unchecked")
public final T readValue(JsonParser p, ResolvedType valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readValue(getDeserializationConfig(), p, (JavaType) valueType);
}
/**
* Type-safe overloaded method, basically alias for {@link #readValue(JsonParser, Class)}.
*
* @throws IOException if a low-level I/O problem (unexpected end-of-input,
* network error) occurs (passed through as-is without additional wrapping -- note
* that this is one case where {@link DeserializationFeature#WRAP_EXCEPTIONS}
* does NOT result in wrapping of exception even if enabled)
* @throws JsonParseException if underlying input contains invalid content
* of type {@link JsonParser} supports (JSON for default case)
* @throws JsonMappingException if the input JSON structure does not match structure
* expected for result type (or has other mismatch issues)
*/
@SuppressWarnings("unchecked")
public T readValue(JsonParser p, JavaType valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readValue(getDeserializationConfig(), p, valueType);
}
/**
* Method to deserialize JSON content as tree expressed
* using set of {@link JsonNode} instances. Returns
* root of the resulting tree (where root can consist
* of just a single node if the current event is a
* value event, not container).
*
* @return a {@link JsonNode}, if valid JSON content found; null
* if input has no content to bind -- note, however, that if
* JSON null
token is found, it will be represented
* as a non-null {@link JsonNode} (one that returns true
* for {@link JsonNode#isNull()}
*
* @throws IOException if a low-level I/O problem (unexpected end-of-input,
* network error) occurs (passed through as-is without additional wrapping -- note
* that this is one case where {@link DeserializationFeature#WRAP_EXCEPTIONS}
* does NOT result in wrapping of exception even if enabled)
* @throws JsonParseException if underlying input contains invalid content
* of type {@link JsonParser} supports (JSON for default case)
*/
@Override
public T readTree(JsonParser p)
throws IOException, JsonProcessingException
{
/* 02-Mar-2009, tatu: One twist; deserialization provider
* will map JSON null straight into Java null. But what
* we want to return is the "null node" instead.
*/
/* 05-Aug-2011, tatu: Also, must check for EOF here before
* calling readValue(), since that'll choke on it otherwise
*/
DeserializationConfig cfg = getDeserializationConfig();
JsonToken t = p.getCurrentToken();
if (t == null) {
t = p.nextToken();
if (t == null) {
return null;
}
}
JsonNode n = (JsonNode) _readValue(cfg, p, JSON_NODE_TYPE);
if (n == null) {
n = getNodeFactory().nullNode();
}
@SuppressWarnings("unchecked")
T result = (T) n;
return result;
}
/**
* Convenience method, equivalent in function to:
*
* readerFor(valueType).readValues(p);
*
*
* Method for reading sequence of Objects from parser stream.
* Sequence can be either root-level "unwrapped" sequence (without surrounding
* JSON array), or a sequence contained in a JSON Array.
* In either case {@link JsonParser} MUST point to the first token of
* the first element, OR not point to any token (in which case it is advanced
* to the next token). This means, specifically, that for wrapped sequences,
* parser MUST NOT point to the surrounding START_ARRAY
(one that
* contains values to read) but rather to the token following it which is the first
* token of the first value to read.
*
* Note that {@link ObjectReader} has more complete set of variants.
*/
@Override
public MappingIterator readValues(JsonParser p, ResolvedType valueType)
throws IOException, JsonProcessingException
{
return readValues(p, (JavaType) valueType);
}
/**
* Convenience method, equivalent in function to:
*
* readerFor(valueType).readValues(p);
*
*
* Type-safe overload of {@link #readValues(JsonParser, ResolvedType)}.
*/
public MappingIterator readValues(JsonParser p, JavaType valueType)
throws IOException, JsonProcessingException
{
DeserializationConfig config = getDeserializationConfig();
DeserializationContext ctxt = createDeserializationContext(p, config);
JsonDeserializer> deser = _findRootDeserializer(ctxt, valueType);
// false -> do NOT close JsonParser (since caller passed it)
return new MappingIterator(valueType, p, ctxt, deser,
false, null);
}
/**
* Convenience method, equivalent in function to:
*
* readerFor(valueType).readValues(p);
*
*
* Type-safe overload of {@link #readValues(JsonParser, ResolvedType)}.
*/
@Override
public MappingIterator readValues(JsonParser p, Class valueType)
throws IOException, JsonProcessingException
{
return readValues(p, _typeFactory.constructType(valueType));
}
/**
* Method for reading sequence of Objects from parser stream.
*/
@Override
public MappingIterator readValues(JsonParser p, TypeReference> valueTypeRef)
throws IOException, JsonProcessingException
{
return readValues(p, _typeFactory.constructType(valueTypeRef));
}
/*
/**********************************************************
/* Public API not included in ObjectCodec: deserialization
/* (mapping from JSON to Java types)
/**********************************************************
*/
/**
* Method to deserialize JSON content as tree expressed
* using set of {@link JsonNode} instances.
* Returns root of the resulting tree (where root can consist
* of just a single node if the current event is a
* value event, not container).
*
* If a low-level I/O problem (missing input, network error) occurs,
* a {@link IOException} will be thrown.
* If a parsing problem occurs (invalid JSON),
* {@link JsonParseException} will be thrown.
* If no content is found from input (end-of-input), Java
* null
will be returned.
*
* @param in Input stream used to read JSON content
* for building the JSON tree.
*
* @return a {@link JsonNode}, if valid JSON content found; null
* if input has no content to bind -- note, however, that if
* JSON null
token is found, it will be represented
* as a non-null {@link JsonNode} (one that returns true
* for {@link JsonNode#isNull()}
*
* @throws JsonParseException if underlying input contains invalid content
* of type {@link JsonParser} supports (JSON for default case)
*/
public JsonNode readTree(InputStream in) throws IOException
{
return _readTreeAndClose(_jsonFactory.createParser(in));
}
/**
* Method to deserialize JSON content as tree expressed
* using set of {@link JsonNode} instances.
* Returns root of the resulting tree (where root can consist
* of just a single node if the current event is a
* value event, not container).
*
* If a low-level I/O problem (missing input, network error) occurs,
* a {@link IOException} will be thrown.
* If a parsing problem occurs (invalid JSON),
* {@link JsonParseException} will be thrown.
* If no content is found from input (end-of-input), Java
* null
will be returned.
*
* @param r Reader used to read JSON content
* for building the JSON tree.
*
* @return a {@link JsonNode}, if valid JSON content found; null
* if input has no content to bind -- note, however, that if
* JSON null
token is found, it will be represented
* as a non-null {@link JsonNode} (one that returns true
* for {@link JsonNode#isNull()}
*/
public JsonNode readTree(Reader r) throws IOException {
return _readTreeAndClose(_jsonFactory.createParser(r));
}
/**
* Method to deserialize JSON content as tree expressed using set of {@link JsonNode} instances.
* Returns root of the resulting tree (where root can consist of just a single node if the current
* event is a value event, not container).
*
* If a low-level I/O problem (missing input, network error) occurs,
* a {@link IOException} will be thrown.
* If a parsing problem occurs (invalid JSON),
* {@link JsonParseException} will be thrown.
* If no content is found from input (end-of-input), Java
* null
will be returned.
*
* @param content JSON content to parse to build the JSON tree.
*
* @return a {@link JsonNode}, if valid JSON content found; null
* if input has no content to bind -- note, however, that if
* JSON null
token is found, it will be represented
* as a non-null {@link JsonNode} (one that returns true
* for {@link JsonNode#isNull()}
*
* @throws JsonParseException if underlying input contains invalid content
* of type {@link JsonParser} supports (JSON for default case)
*/
public JsonNode readTree(String content) throws IOException {
return _readTreeAndClose(_jsonFactory.createParser(content));
}
/**
* Method to deserialize JSON content as tree expressed using set of {@link JsonNode} instances.
* Returns root of the resulting tree (where root can consist of just a single node if the current
* event is a value event, not container).
*
* @param content JSON content to parse to build the JSON tree.
*
* @return a {@link JsonNode}, if valid JSON content found; null
* if input has no content to bind -- note, however, that if
* JSON null
token is found, it will be represented
* as a non-null {@link JsonNode} (one that returns true
* for {@link JsonNode#isNull()}
*
* @throws JsonParseException if underlying input contains invalid content
* of type {@link JsonParser} supports (JSON for default case)
*/
public JsonNode readTree(byte[] content) throws IOException {
return _readTreeAndClose(_jsonFactory.createParser(content));
}
/**
* Method to deserialize JSON content as tree expressed using set of {@link JsonNode} instances.
* Returns root of the resulting tree (where root can consist of just a single node if the current
* event is a value event, not container).
*
* @param file File of which contents to parse as JSON for building a tree instance
*
* @return a {@link JsonNode}, if valid JSON content found; null
* if input has no content to bind -- note, however, that if
* JSON null
token is found, it will be represented
* as a non-null {@link JsonNode} (one that returns true
* for {@link JsonNode#isNull()}
*
* @throws IOException if a low-level I/O problem (unexpected end-of-input,
* network error) occurs (passed through as-is without additional wrapping -- note
* that this is one case where {@link DeserializationFeature#WRAP_EXCEPTIONS}
* does NOT result in wrapping of exception even if enabled)
* @throws JsonParseException if underlying input contains invalid content
* of type {@link JsonParser} supports (JSON for default case)
*/
public JsonNode readTree(File file)
throws IOException, JsonProcessingException
{
return _readTreeAndClose(_jsonFactory.createParser(file));
}
/**
* Method to deserialize JSON content as tree expressed using set of {@link JsonNode} instances.
* Returns root of the resulting tree (where root can consist of just a single node if the current
* event is a value event, not container).
*
* @param source URL to use for fetching contents to parse as JSON for building a tree instance
*
* @return a {@link JsonNode}, if valid JSON content found; null
* if input has no content to bind -- note, however, that if
* JSON null
token is found, it will be represented
* as a non-null {@link JsonNode} (one that returns true
* for {@link JsonNode#isNull()}
*
* @throws IOException if a low-level I/O problem (unexpected end-of-input,
* network error) occurs (passed through as-is without additional wrapping -- note
* that this is one case where {@link DeserializationFeature#WRAP_EXCEPTIONS}
* does NOT result in wrapping of exception even if enabled)
* @throws JsonParseException if underlying input contains invalid content
* of type {@link JsonParser} supports (JSON for default case)
*/
public JsonNode readTree(URL source) throws IOException {
return _readTreeAndClose(_jsonFactory.createParser(source));
}
/*
/**********************************************************
/* Public API (from ObjectCodec): serialization
/* (mapping from Java types to Json)
/**********************************************************
*/
/**
* Method that can be used to serialize any Java value as
* JSON output, using provided {@link JsonGenerator}.
*/
@Override
public void writeValue(JsonGenerator g, Object value)
throws IOException, JsonGenerationException, JsonMappingException
{
SerializationConfig config = getSerializationConfig();
/* 12-May-2015/2.6, tatu: Looks like we do NOT want to call the usual
* 'config.initialize(g)` here, since it is assumed that generator
* has been configured by caller. But for some reason we don't
* trust indentation settings...
*/
// 10-Aug-2012, tatu: as per [Issue#12], must handle indentation:
if (config.isEnabled(SerializationFeature.INDENT_OUTPUT)) {
if (g.getPrettyPrinter() == null) {
g.setPrettyPrinter(config.constructDefaultPrettyPrinter());
}
}
if (config.isEnabled(SerializationFeature.CLOSE_CLOSEABLE) && (value instanceof Closeable)) {
_writeCloseableValue(g, value, config);
} else {
_serializerProvider(config).serializeValue(g, value);
if (config.isEnabled(SerializationFeature.FLUSH_AFTER_WRITE_VALUE)) {
g.flush();
}
}
}
/*
/**********************************************************
/* Public API (from TreeCodec via ObjectCodec): Tree Model support
/**********************************************************
*/
@Override
public void writeTree(JsonGenerator jgen, TreeNode rootNode)
throws IOException, JsonProcessingException
{
SerializationConfig config = getSerializationConfig();
_serializerProvider(config).serializeValue(jgen, rootNode);
if (config.isEnabled(SerializationFeature.FLUSH_AFTER_WRITE_VALUE)) {
jgen.flush();
}
}
/**
* Method to serialize given JSON Tree, using generator
* provided.
*/
public void writeTree(JsonGenerator jgen, JsonNode rootNode)
throws IOException, JsonProcessingException
{
SerializationConfig config = getSerializationConfig();
_serializerProvider(config).serializeValue(jgen, rootNode);
if (config.isEnabled(SerializationFeature.FLUSH_AFTER_WRITE_VALUE)) {
jgen.flush();
}
}
/**
*
* Note: return type is co-variant, as basic ObjectCodec
* abstraction cannot refer to concrete node types (as it's
* part of core package, whereas impls are part of mapper
* package)
*/
@Override
public ObjectNode createObjectNode() {
return _deserializationConfig.getNodeFactory().objectNode();
}
/**
*
* Note: return type is co-variant, as basic ObjectCodec
* abstraction cannot refer to concrete node types (as it's
* part of core package, whereas impls are part of mapper
* package)
*/
@Override
public ArrayNode createArrayNode() {
return _deserializationConfig.getNodeFactory().arrayNode();
}
/**
* Method for constructing a {@link JsonParser} out of JSON tree
* representation.
*
* @param n Root node of the tree that resulting parser will read from
*/
@Override
public JsonParser treeAsTokens(TreeNode n) {
return new TreeTraversingParser((JsonNode) n, this);
}
/**
* Convenience conversion method that will bind data given JSON tree
* contains into specific value (usually bean) type.
*
* Functionally equivalent to:
*
* objectMapper.convertValue(n, valueClass);
*
*/
@SuppressWarnings("unchecked")
@Override
public T treeToValue(TreeNode n, Class valueType)
throws JsonProcessingException
{
try {
// Simple cast when we just want to cast to, say, ObjectNode
// ... one caveat; while everything is Object.class, let's not take shortcut
if (valueType != Object.class && valueType.isAssignableFrom(n.getClass())) {
return (T) n;
}
// 20-Apr-2016, tatu: Another thing: for VALUE_EMBEDDED_OBJECT, assume similar
// short-cut coercion
if (n.asToken() == JsonToken.VALUE_EMBEDDED_OBJECT) {
if (n instanceof POJONode) {
Object ob = ((POJONode) n).getPojo();
if ((ob == null) || valueType.isInstance(ob)) {
return (T) ob;
}
}
}
return readValue(treeAsTokens(n), valueType);
} catch (JsonProcessingException e) {
throw e;
} catch (IOException e) { // should not occur, no real i/o...
throw new IllegalArgumentException(e.getMessage(), e);
}
}
/**
* Reverse of {@link #treeToValue}; given a value (usually bean), will
* construct equivalent JSON Tree representation. Functionally similar
* to serializing value into JSON and parsing JSON as tree, but
* more efficient.
*
* NOTE: while results are usually identical to that of serialization followed
* by deserialization, this is not always the case. In some cases serialization
* into intermediate representation will retain encapsulation of things like
* raw value ({@link com.pdd.pop.ext.fasterxml.jackson.databind.util.RawValue}) or basic
* node identity ({@link JsonNode}). If so, result is a valid tree, but values
* are not re-constructed through actual JSON representation. So if transformation
* requires actual materialization of JSON (or other data format that this mapper
* produces), it will be necessary to do actual serialization.
*
* @param Actual node type; usually either basic {@link JsonNode} or
* {@link com.pdd.pop.ext.fasterxml.jackson.databind.node.ObjectNode}
* @param fromValue Bean value to convert
* @return Root node of the resulting JSON tree
*/
@SuppressWarnings({ "unchecked", "resource" })
public T valueToTree(Object fromValue)
throws IllegalArgumentException
{
if (fromValue == null) return null;
TokenBuffer buf = new TokenBuffer(this, false);
if (isEnabled(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)) {
buf = buf.forceUseOfBigDecimal(true);
}
JsonNode result;
try {
writeValue(buf, fromValue);
JsonParser p = buf.asParser();
result = readTree(p);
p.close();
} catch (IOException e) { // should not occur, no real i/o...
throw new IllegalArgumentException(e.getMessage(), e);
}
return (T) result;
}
/*
/**********************************************************
/* Extended Public API, accessors
/**********************************************************
*/
/**
* Method that can be called to check whether mapper thinks
* it could serialize an instance of given Class.
* Check is done
* by checking whether a serializer can be found for the type.
*
* NOTE: since this method does NOT throw exceptions, but internal
* processing may, caller usually has little information as to why
* serialization would fail. If you want access to internal {@link Exception},
* call {@link #canSerialize(Class, AtomicReference)} instead.
*
* @return True if mapper can find a serializer for instances of
* given class (potentially serializable), false otherwise (not
* serializable)
*/
public boolean canSerialize(Class> type) {
return _serializerProvider(getSerializationConfig()).hasSerializerFor(type, null);
}
/**
* Method similar to {@link #canSerialize(Class)} but that can return
* actual {@link Throwable} that was thrown when trying to construct
* serializer: this may be useful in figuring out what the actual problem is.
*
* @since 2.3
*/
public boolean canSerialize(Class> type, AtomicReference cause) {
return _serializerProvider(getSerializationConfig()).hasSerializerFor(type, cause);
}
/**
* Method that can be called to check whether mapper thinks
* it could deserialize an Object of given type.
* Check is done by checking whether a registered deserializer can
* be found or built for the type; if not (either by no mapping being
* found, or through an Exception
being thrown, false
* is returned.
*
* NOTE : in case an exception is thrown during course of trying
* co construct matching deserializer, it will be effectively swallowed.
* If you want access to that exception, call
* {@link #canDeserialize(JavaType, AtomicReference)} instead.
*
* @return True if mapper can find a serializer for instances of
* given class (potentially serializable), false otherwise (not
* serializable)
*/
public boolean canDeserialize(JavaType type)
{
return createDeserializationContext(null,
getDeserializationConfig()).hasValueDeserializerFor(type, null);
}
/**
* Method similar to {@link #canDeserialize(JavaType)} but that can return
* actual {@link Throwable} that was thrown when trying to construct
* serializer: this may be useful in figuring out what the actual problem is.
*
* @since 2.3
*/
public boolean canDeserialize(JavaType type, AtomicReference cause)
{
return createDeserializationContext(null,
getDeserializationConfig()).hasValueDeserializerFor(type, cause);
}
/*
/**********************************************************
/* Extended Public API, deserialization,
/* convenience methods
/**********************************************************
*/
/**
* Method to deserialize JSON content from given file into given Java type.
*
* @throws IOException if a low-level I/O problem (unexpected end-of-input,
* network error) occurs (passed through as-is without additional wrapping -- note
* that this is one case where {@link DeserializationFeature#WRAP_EXCEPTIONS}
* does NOT result in wrapping of exception even if enabled)
* @throws JsonParseException if underlying input contains invalid content
* of type {@link JsonParser} supports (JSON for default case)
* @throws JsonMappingException if the input JSON structure does not match structure
* expected for result type (or has other mismatch issues)
*/
@SuppressWarnings("unchecked")
public T readValue(File src, Class valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueType));
}
/**
* Method to deserialize JSON content from given file into given Java type.
*
* @throws IOException if a low-level I/O problem (unexpected end-of-input,
* network error) occurs (passed through as-is without additional wrapping -- note
* that this is one case where {@link DeserializationFeature#WRAP_EXCEPTIONS}
* does NOT result in wrapping of exception even if enabled)
* @throws JsonParseException if underlying input contains invalid content
* of type {@link JsonParser} supports (JSON for default case)
* @throws JsonMappingException if the input JSON structure does not match structure
* expected for result type (or has other mismatch issues)
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public T readValue(File src, TypeReference valueTypeRef)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueTypeRef));
}
/**
* Method to deserialize JSON content from given file into given Java type.
*
* @throws IOException if a low-level I/O problem (unexpected end-of-input,
* network error) occurs (passed through as-is without additional wrapping -- note
* that this is one case where {@link DeserializationFeature#WRAP_EXCEPTIONS}
* does NOT result in wrapping of exception even if enabled)
* @throws JsonParseException if underlying input contains invalid content
* of type {@link JsonParser} supports (JSON for default case)
* @throws JsonMappingException if the input JSON structure does not match structure
* expected for result type (or has other mismatch issues)
*/
@SuppressWarnings("unchecked")
public T readValue(File src, JavaType valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createParser(src), valueType);
}
/**
* Method to deserialize JSON content from given resource into given Java type.
*
* @throws IOException if a low-level I/O problem (unexpected end-of-input,
* network error) occurs (passed through as-is without additional wrapping -- note
* that this is one case where {@link DeserializationFeature#WRAP_EXCEPTIONS}
* does NOT result in wrapping of exception even if enabled)
* @throws JsonParseException if underlying input contains invalid content
* of type {@link JsonParser} supports (JSON for default case)
* @throws JsonMappingException if the input JSON structure does not match structure
* expected for result type (or has other mismatch issues)
*/
@SuppressWarnings("unchecked")
public T readValue(URL src, Class valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueType));
}
/**
* Method to deserialize JSON content from given resource into given Java type.
*
* @throws IOException if a low-level I/O problem (unexpected end-of-input,
* network error) occurs (passed through as-is without additional wrapping -- note
* that this is one case where {@link DeserializationFeature#WRAP_EXCEPTIONS}
* does NOT result in wrapping of exception even if enabled)
* @throws JsonParseException if underlying input contains invalid content
* of type {@link JsonParser} supports (JSON for default case)
* @throws JsonMappingException if the input JSON structure does not match structure
* expected for result type (or has other mismatch issues)
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public T readValue(URL src, TypeReference valueTypeRef)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueTypeRef));
}
@SuppressWarnings("unchecked")
public T readValue(URL src, JavaType valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createParser(src), valueType);
}
/**
* Method to deserialize JSON content from given JSON content String.
*
* @throws IOException if a low-level I/O problem (unexpected end-of-input,
* network error) occurs (passed through as-is without additional wrapping -- note
* that this is one case where {@link DeserializationFeature#WRAP_EXCEPTIONS}
* does NOT result in wrapping of exception even if enabled)
* @throws JsonParseException if underlying input contains invalid content
* of type {@link JsonParser} supports (JSON for default case)
* @throws JsonMappingException if the input JSON structure does not match structure
* expected for result type (or has other mismatch issues)
*/
@SuppressWarnings("unchecked")
public T readValue(String content, Class valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createParser(content), _typeFactory.constructType(valueType));
}
/**
* Method to deserialize JSON content from given JSON content String.
*
* @throws IOException if a low-level I/O problem (unexpected end-of-input,
* network error) occurs (passed through as-is without additional wrapping -- note
* that this is one case where {@link DeserializationFeature#WRAP_EXCEPTIONS}
* does NOT result in wrapping of exception even if enabled)
* @throws JsonParseException if underlying input contains invalid content
* of type {@link JsonParser} supports (JSON for default case)
* @throws JsonMappingException if the input JSON structure does not match structure
* expected for result type (or has other mismatch issues)
*/
@SuppressWarnings({ "unchecked", "rawtypes" })
public T readValue(String content, TypeReference valueTypeRef)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createParser(content), _typeFactory.constructType(valueTypeRef));
}
/**
* Method to deserialize JSON content from given JSON content String.
*
* @throws IOException if a low-level I/O problem (unexpected end-of-input,
* network error) occurs (passed through as-is without additional wrapping -- note
* that this is one case where {@link DeserializationFeature#WRAP_EXCEPTIONS}
* does NOT result in wrapping of exception even if enabled)
* @throws JsonParseException if underlying input contains invalid content
* of type {@link JsonParser} supports (JSON for default case)
* @throws JsonMappingException if the input JSON structure does not match structure
* expected for result type (or has other mismatch issues)
*/
@SuppressWarnings("unchecked")
public T readValue(String content, JavaType valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createParser(content), valueType);
}
@SuppressWarnings("unchecked")
public T readValue(Reader src, Class valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueType));
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public T readValue(Reader src, TypeReference valueTypeRef)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueTypeRef));
}
@SuppressWarnings("unchecked")
public T readValue(Reader src, JavaType valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createParser(src), valueType);
}
@SuppressWarnings("unchecked")
public T readValue(InputStream src, Class valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueType));
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public T readValue(InputStream src, TypeReference valueTypeRef)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueTypeRef));
}
@SuppressWarnings("unchecked")
public T readValue(InputStream src, JavaType valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createParser(src), valueType);
}
@SuppressWarnings("unchecked")
public T readValue(byte[] src, Class valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueType));
}
@SuppressWarnings("unchecked")
public T readValue(byte[] src, int offset, int len,
Class valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createParser(src, offset, len), _typeFactory.constructType(valueType));
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public T readValue(byte[] src, TypeReference valueTypeRef)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createParser(src), _typeFactory.constructType(valueTypeRef));
}
@SuppressWarnings({ "unchecked", "rawtypes" })
public T readValue(byte[] src, int offset, int len,
TypeReference valueTypeRef)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createParser(src, offset, len), _typeFactory.constructType(valueTypeRef));
}
@SuppressWarnings("unchecked")
public T readValue(byte[] src, JavaType valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createParser(src), valueType);
}
@SuppressWarnings("unchecked")
public T readValue(byte[] src, int offset, int len,
JavaType valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createParser(src, offset, len), valueType);
}
@SuppressWarnings("unchecked")
public T readValue(DataInput src, Class valueType) throws IOException
{
return (T) _readMapAndClose(_jsonFactory.createParser(src),
_typeFactory.constructType(valueType));
}
@SuppressWarnings("unchecked")
public T readValue(DataInput src, JavaType valueType) throws IOException
{
return (T) _readMapAndClose(_jsonFactory.createParser(src), valueType);
}
/*
/**********************************************************
/* Extended Public API: serialization
/* (mapping from Java types to JSON)
/**********************************************************
*/
/**
* Method that can be used to serialize any Java value as
* JSON output, written to File provided.
*/
public void writeValue(File resultFile, Object value)
throws IOException, JsonGenerationException, JsonMappingException
{
_configAndWriteValue(_jsonFactory.createGenerator(resultFile, JsonEncoding.UTF8), value);
}
/**
* Method that can be used to serialize any Java value as
* JSON output, using output stream provided (using encoding
* {@link JsonEncoding#UTF8}).
*
* Note: method does not close the underlying stream explicitly
* here; however, {@link JsonFactory} this mapper uses may choose
* to close the stream depending on its settings (by default,
* it will try to close it when {@link JsonGenerator} we construct
* is closed).
*/
public void writeValue(OutputStream out, Object value)
throws IOException, JsonGenerationException, JsonMappingException
{
_configAndWriteValue(_jsonFactory.createGenerator(out, JsonEncoding.UTF8), value);
}
/**
* @since 2.8
*/
public void writeValue(DataOutput out, Object value)
throws IOException
{
_configAndWriteValue(_jsonFactory.createGenerator(out, JsonEncoding.UTF8), value);
}
/**
* Method that can be used to serialize any Java value as
* JSON output, using Writer provided.
*
* Note: method does not close the underlying stream explicitly
* here; however, {@link JsonFactory} this mapper uses may choose
* to close the stream depending on its settings (by default,
* it will try to close it when {@link JsonGenerator} we construct
* is closed).
*/
public void writeValue(Writer w, Object value)
throws IOException, JsonGenerationException, JsonMappingException
{
_configAndWriteValue(_jsonFactory.createGenerator(w), value);
}
/**
* Method that can be used to serialize any Java value as
* a String. Functionally equivalent to calling
* {@link #writeValue(Writer,Object)} with {@link java.io.StringWriter}
* and constructing String, but more efficient.
*
* Note: prior to version 2.1, throws clause included {@link IOException}; 2.1 removed it.
*/
@SuppressWarnings("resource")
public String writeValueAsString(Object value)
throws JsonProcessingException
{
// alas, we have to pull the recycler directly here...
SegmentedStringWriter sw = new SegmentedStringWriter(_jsonFactory._getBufferRecycler());
try {
_configAndWriteValue(_jsonFactory.createGenerator(sw), value);
} catch (JsonProcessingException e) {
throw e;
} catch (IOException e) { // shouldn't really happen, but is declared as possibility so:
throw JsonMappingException.fromUnexpectedIOE(e);
}
return sw.getAndClear();
}
/**
* Method that can be used to serialize any Java value as
* a byte array. Functionally equivalent to calling
* {@link #writeValue(Writer,Object)} with {@link java.io.ByteArrayOutputStream}
* and getting bytes, but more efficient.
* Encoding used will be UTF-8.
*
* Note: prior to version 2.1, throws clause included {@link IOException}; 2.1 removed it.
*/
@SuppressWarnings("resource")
public byte[] writeValueAsBytes(Object value)
throws JsonProcessingException
{
ByteArrayBuilder bb = new ByteArrayBuilder(_jsonFactory._getBufferRecycler());
try {
_configAndWriteValue(_jsonFactory.createGenerator(bb, JsonEncoding.UTF8), value);
} catch (JsonProcessingException e) { // to support [JACKSON-758]
throw e;
} catch (IOException e) { // shouldn't really happen, but is declared as possibility so:
throw JsonMappingException.fromUnexpectedIOE(e);
}
byte[] result = bb.toByteArray();
bb.release();
return result;
}
/*
/**********************************************************
/* Extended Public API: constructing ObjectWriters
/* for more advanced configuration
/**********************************************************
*/
/**
* Convenience method for constructing {@link ObjectWriter}
* with default settings.
*/
public ObjectWriter writer() {
return _newWriter(getSerializationConfig());
}
/**
* Factory method for constructing {@link ObjectWriter} with
* specified feature enabled (compared to settings that this
* mapper instance has).
*/
public ObjectWriter writer(SerializationFeature feature) {
return _newWriter(getSerializationConfig().with(feature));
}
/**
* Factory method for constructing {@link ObjectWriter} with
* specified features enabled (compared to settings that this
* mapper instance has).
*/
public ObjectWriter writer(SerializationFeature first,
SerializationFeature... other) {
return _newWriter(getSerializationConfig().with(first, other));
}
/**
* Factory method for constructing {@link ObjectWriter} that will
* serialize objects using specified {@link DateFormat}; or, if
* null passed, using timestamp (64-bit number.
*/
public ObjectWriter writer(DateFormat df) {
return _newWriter(getSerializationConfig().with(df));
}
/**
* Factory method for constructing {@link ObjectWriter} that will
* serialize objects using specified JSON View (filter).
*/
public ObjectWriter writerWithView(Class> serializationView) {
return _newWriter(getSerializationConfig().withView(serializationView));
}
/**
* Factory method for constructing {@link ObjectWriter} that will
* serialize objects using specified root type, instead of actual
* runtime type of value. Type must be a super-type of runtime type.
*
* Main reason for using this method is performance, as writer is able
* to pre-fetch serializer to use before write, and if writer is used
* more than once this avoids addition per-value serializer lookups.
*
* @since 2.5
*/
public ObjectWriter writerFor(Class> rootType) {
return _newWriter(getSerializationConfig(),
((rootType == null) ? null :_typeFactory.constructType(rootType)),
/*PrettyPrinter*/null);
}
/**
* Factory method for constructing {@link ObjectWriter} that will
* serialize objects using specified root type, instead of actual
* runtime type of value. Type must be a super-type of runtime type.
*
* Main reason for using this method is performance, as writer is able
* to pre-fetch serializer to use before write, and if writer is used
* more than once this avoids addition per-value serializer lookups.
*
* @since 2.5
*/
public ObjectWriter writerFor(TypeReference> rootType) {
return _newWriter(getSerializationConfig(),
((rootType == null) ? null : _typeFactory.constructType(rootType)),
/*PrettyPrinter*/null);
}
/**
* Factory method for constructing {@link ObjectWriter} that will
* serialize objects using specified root type, instead of actual
* runtime type of value. Type must be a super-type of runtime type.
*
* Main reason for using this method is performance, as writer is able
* to pre-fetch serializer to use before write, and if writer is used
* more than once this avoids addition per-value serializer lookups.
*
* @since 2.5
*/
public ObjectWriter writerFor(JavaType rootType) {
return _newWriter(getSerializationConfig(), rootType, /*PrettyPrinter*/null);
}
/**
* Factory method for constructing {@link ObjectWriter} that will
* serialize objects using specified pretty printer for indentation
* (or if null, no pretty printer)
*/
public ObjectWriter writer(PrettyPrinter pp) {
if (pp == null) { // need to use a marker to indicate explicit disabling of pp
pp = ObjectWriter.NULL_PRETTY_PRINTER;
}
return _newWriter(getSerializationConfig(), /*root type*/ null, pp);
}
/**
* Factory method for constructing {@link ObjectWriter} that will
* serialize objects using the default pretty printer for indentation
*/
public ObjectWriter writerWithDefaultPrettyPrinter() {
SerializationConfig config = getSerializationConfig();
return _newWriter(config,
/*root type*/ null, config.getDefaultPrettyPrinter());
}
/**
* Factory method for constructing {@link ObjectWriter} that will
* serialize objects using specified filter provider.
*/
public ObjectWriter writer(FilterProvider filterProvider) {
return _newWriter(getSerializationConfig().withFilters(filterProvider));
}
/**
* Factory method for constructing {@link ObjectWriter} that will
* pass specific schema object to {@link JsonGenerator} used for
* writing content.
*
* @param schema Schema to pass to generator
*/
public ObjectWriter writer(FormatSchema schema) {
_verifySchemaType(schema);
return _newWriter(getSerializationConfig(), schema);
}
/**
* Factory method for constructing {@link ObjectWriter} that will
* use specified Base64 encoding variant for Base64-encoded binary data.
*
* @since 2.1
*/
public ObjectWriter writer(Base64Variant defaultBase64) {
return _newWriter(getSerializationConfig().with(defaultBase64));
}
/**
* Factory method for constructing {@link ObjectReader} that will
* use specified character escaping details for output.
*
* @since 2.3
*/
public ObjectWriter writer(CharacterEscapes escapes) {
return _newWriter(getSerializationConfig()).with(escapes);
}
/**
* Factory method for constructing {@link ObjectWriter} that will
* use specified default attributes.
*
* @since 2.3
*/
public ObjectWriter writer(ContextAttributes attrs) {
return _newWriter(getSerializationConfig().with(attrs));
}
/**
* @deprecated Since 2.5, use {@link #writerFor(Class)} instead
*/
@Deprecated
public ObjectWriter writerWithType(Class> rootType) {
return _newWriter(getSerializationConfig(),
// 15-Mar-2013, tatu: Important! Indicate that static typing is needed:
((rootType == null) ? null :_typeFactory.constructType(rootType)),
/*PrettyPrinter*/null);
}
/**
* @deprecated Since 2.5, use {@link #writerFor(TypeReference)} instead
*/
@Deprecated
public ObjectWriter writerWithType(TypeReference> rootType) {
return _newWriter(getSerializationConfig(),
// 15-Mar-2013, tatu: Important! Indicate that static typing is needed:
((rootType == null) ? null : _typeFactory.constructType(rootType)),
/*PrettyPrinter*/null);
}
/**
* @deprecated Since 2.5, use {@link #writerFor(JavaType)} instead
*/
@Deprecated
public ObjectWriter writerWithType(JavaType rootType) {
return _newWriter(getSerializationConfig(), rootType, /*PrettyPrinter*/null);
}
/*
/**********************************************************
/* Extended Public API: constructing ObjectReaders
/* for more advanced configuration
/**********************************************************
*/
/**
* Factory method for constructing {@link ObjectReader} with
* default settings. Note that the resulting instance is NOT usable as is,
* without defining expected value type.
*/
public ObjectReader reader() {
return _newReader(getDeserializationConfig()).with(_injectableValues);
}
/**
* Factory method for constructing {@link ObjectReader} with
* specified feature enabled (compared to settings that this
* mapper instance has).
* Note that the resulting instance is NOT usable as is,
* without defining expected value type.
*/
public ObjectReader reader(DeserializationFeature feature) {
return _newReader(getDeserializationConfig().with(feature));
}
/**
* Factory method for constructing {@link ObjectReader} with
* specified features enabled (compared to settings that this
* mapper instance has).
* Note that the resulting instance is NOT usable as is,
* without defining expected value type.
*/
public ObjectReader reader(DeserializationFeature first,
DeserializationFeature... other) {
return _newReader(getDeserializationConfig().with(first, other));
}
/**
* Factory method for constructing {@link ObjectReader} that will
* update given Object (usually Bean, but can be a Collection or Map
* as well, but NOT an array) with JSON data. Deserialization occurs
* normally except that the root-level value in JSON is not used for
* instantiating a new object; instead give updateable object is used
* as root.
* Runtime type of value object is used for locating deserializer,
* unless overridden by other factory methods of {@link ObjectReader}
*/
public ObjectReader readerForUpdating(Object valueToUpdate) {
JavaType t = _typeFactory.constructType(valueToUpdate.getClass());
return _newReader(getDeserializationConfig(), t, valueToUpdate,
null, _injectableValues);
}
/**
* Factory method for constructing {@link ObjectReader} that will
* read or update instances of specified type
*
* @since 2.6
*/
public ObjectReader readerFor(JavaType type) {
return _newReader(getDeserializationConfig(), type, null,
null, _injectableValues);
}
/**
* Factory method for constructing {@link ObjectReader} that will
* read or update instances of specified type
*
* @since 2.6
*/
public ObjectReader readerFor(Class> type) {
return _newReader(getDeserializationConfig(), _typeFactory.constructType(type), null,
null, _injectableValues);
}
/**
* Factory method for constructing {@link ObjectReader} that will
* read or update instances of specified type
*
* @since 2.6
*/
public ObjectReader readerFor(TypeReference> type) {
return _newReader(getDeserializationConfig(), _typeFactory.constructType(type), null,
null, _injectableValues);
}
/**
* Factory method for constructing {@link ObjectReader} that will
* use specified {@link JsonNodeFactory} for constructing JSON trees.
*/
public ObjectReader reader(JsonNodeFactory f) {
return _newReader(getDeserializationConfig()).with(f);
}
/**
* Factory method for constructing {@link ObjectReader} that will
* pass specific schema object to {@link JsonParser} used for
* reading content.
*
* @param schema Schema to pass to parser
*/
public ObjectReader reader(FormatSchema schema) {
_verifySchemaType(schema);
return _newReader(getDeserializationConfig(), null, null,
schema, _injectableValues);
}
/**
* Factory method for constructing {@link ObjectReader} that will
* use specified injectable values.
*
* @param injectableValues Injectable values to use
*/
public ObjectReader reader(InjectableValues injectableValues) {
return _newReader(getDeserializationConfig(), null, null,
null, injectableValues);
}
/**
* Factory method for constructing {@link ObjectReader} that will
* deserialize objects using specified JSON View (filter).
*/
public ObjectReader readerWithView(Class> view) {
return _newReader(getDeserializationConfig().withView(view));
}
/**
* Factory method for constructing {@link ObjectReader} that will
* use specified Base64 encoding variant for Base64-encoded binary data.
*
* @since 2.1
*/
public ObjectReader reader(Base64Variant defaultBase64) {
return _newReader(getDeserializationConfig().with(defaultBase64));
}
/**
* Factory method for constructing {@link ObjectReader} that will
* use specified default attributes.
*
* @since 2.3
*/
public ObjectReader reader(ContextAttributes attrs) {
return _newReader(getDeserializationConfig().with(attrs));
}
/**
* @deprecated Since 2.5, use {@link #readerFor(JavaType)} instead
*/
@Deprecated
public ObjectReader reader(JavaType type) {
return _newReader(getDeserializationConfig(), type, null,
null, _injectableValues);
}
/**
* @deprecated Since 2.5, use {@link #readerFor(Class)} instead
*/
@Deprecated
public ObjectReader reader(Class> type) {
return _newReader(getDeserializationConfig(), _typeFactory.constructType(type), null,
null, _injectableValues);
}
/**
* @deprecated Since 2.5, use {@link #readerFor(TypeReference)} instead
*/
@Deprecated
public ObjectReader reader(TypeReference> type) {
return _newReader(getDeserializationConfig(), _typeFactory.constructType(type), null,
null, _injectableValues);
}
/*
/**********************************************************
/* Extended Public API: convenience type conversion
/**********************************************************
*/
/**
* Convenience method for doing two-step conversion from given value, into
* instance of given value type, if (but only if!) conversion is needed.
* If given value is already of requested type, value is returned as is.
*
* This method is functionally similar to first
* serializing given value into JSON, and then binding JSON data into value
* of given type, but should be more efficient since full serialization does
* not (need to) occur.
* However, same converters (serializers, deserializers) will be used as for
* data binding, meaning same object mapper configuration works.
*
* Note that it is possible that in some cases behavior does differ from
* full serialize-then-deserialize cycle: in most case differences are
* unintentional (that is, flaws to fix) and should be reported.
* It is not guaranteed, however, that the behavior is 100% the same:
* the goal is just to allow efficient value conversions for structurally
* compatible Objects, according to standard Jackson configuration.
*
* Further note that functianality is not designed to support "advanced" use
* cases, such as conversion of polymorphic values, or cases where Object Identity
* is used.
*
* @throws IllegalArgumentException If conversion fails due to incompatible type;
* if so, root cause will contain underlying checked exception data binding
* functionality threw
*/
@SuppressWarnings("unchecked")
public T convertValue(Object fromValue, Class toValueType)
throws IllegalArgumentException
{
return (T) _convert(fromValue, _typeFactory.constructType(toValueType));
}
/**
* See {@link #convertValue(Object, Class)}
*/
@SuppressWarnings("unchecked")
public T convertValue(Object fromValue, TypeReference> toValueTypeRef)
throws IllegalArgumentException
{
return (T) _convert(fromValue, _typeFactory.constructType(toValueTypeRef));
}
/**
* See {@link #convertValue(Object, Class)}
*/
@SuppressWarnings("unchecked")
public T convertValue(Object fromValue, JavaType toValueType)
throws IllegalArgumentException
{
return (T) _convert(fromValue, toValueType);
}
/**
* Actual conversion implementation: instead of using existing read
* and write methods, much of code is inlined. Reason for this is
* that we must avoid root value wrapping/unwrapping both for efficiency and
* for correctness. If root value wrapping/unwrapping is actually desired,
* caller must use explicit writeValue
and
* readValue
methods.
*/
@SuppressWarnings("resource")
protected Object _convert(Object fromValue, JavaType toValueType)
throws IllegalArgumentException
{
// [databind#1433] Do not shortcut null values.
// This defaults primitives and fires deserializer getNullValue hooks.
if (fromValue != null) {
// also, as per [databind#11], consider case for simple cast
// But with caveats: one is that while everything is Object.class, we don't
// want to "optimize" that out; and the other is that we also do not want
// to lose conversions of generic types.
Class> targetType = toValueType.getRawClass();
if (targetType != Object.class
&& !toValueType.hasGenericTypes()
&& targetType.isAssignableFrom(fromValue.getClass())) {
return fromValue;
}
}
// Then use TokenBuffer, which is a JsonGenerator:
TokenBuffer buf = new TokenBuffer(this, false);
if (isEnabled(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)) {
buf = buf.forceUseOfBigDecimal(true);
}
try {
// inlined 'writeValue' with minor changes:
// first: disable wrapping when writing
SerializationConfig config = getSerializationConfig().without(SerializationFeature.WRAP_ROOT_VALUE);
// no need to check for closing of TokenBuffer
_serializerProvider(config).serializeValue(buf, fromValue);
// then matching read, inlined 'readValue' with minor mods:
final JsonParser p = buf.asParser();
Object result;
// ok to pass in existing feature flags; unwrapping handled by mapper
final DeserializationConfig deserConfig = getDeserializationConfig();
JsonToken t = _initForReading(p, toValueType);
if (t == JsonToken.VALUE_NULL) {
DeserializationContext ctxt = createDeserializationContext(p, deserConfig);
result = _findRootDeserializer(ctxt, toValueType).getNullValue(ctxt);
} else if (t == JsonToken.END_ARRAY || t == JsonToken.END_OBJECT) {
result = null;
} else { // pointing to event other than null
DeserializationContext ctxt = createDeserializationContext(p, deserConfig);
JsonDeserializer deser = _findRootDeserializer(ctxt, toValueType);
// note: no handling of unwrapping
result = deser.deserialize(p, ctxt);
}
p.close();
return result;
} catch (IOException e) { // should not occur, no real i/o...
throw new IllegalArgumentException(e.getMessage(), e);
}
}
/**
* Convenience method similar to {@link #convertValue(Object, JavaType)} but one
* in which
*
* Implementation is approximately as follows:
*
* Serialize `updateWithValue` into {@link TokenBuffer}
* Construct {@link ObjectReader} with `valueToUpdate` (using {@link #readerForUpdating(Object)})
*
* Construct {@link JsonParser} (using {@link TokenBuffer#asParser()})
*
* Update using {@link ObjectReader#readValue(JsonParser)}.
*
* Return `valueToUpdate`
*
*
*
* Note that update is "shallow" in that only first level of properties (or, immediate contents
* of container to update) are modified, unless properties themselves indicate that
* merging should be applied for contents. Such merging can be specified using
* annotations (see JsonMerge
) as well as using "config overrides" (see
* {@link #configOverride(Class)} and {@link #setDefaultMergeable(Boolean)}).
*
* @param valueToUpdate Object to update
* @param overrides Object to conceptually serialize and merge into value to
* update; can be thought of as a provider for overrides to apply.
*
* @return Either the first argument (`valueToUpdate`), if it is mutable; or a result of
* creating new instance that is result of "merging" values (for example, "updating" a
* Java array will create a new array)
*
* @throws JsonMappingException if there are structural incompatibilities that prevent update.
*
* @since 2.9
*/
@SuppressWarnings("resource")
public T updateValue(T valueToUpdate, Object overrides)
throws JsonMappingException
{
T result = valueToUpdate;
if ((valueToUpdate != null) && (overrides != null)) {
TokenBuffer buf = new TokenBuffer(this, false);
if (isEnabled(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS)) {
buf = buf.forceUseOfBigDecimal(true);
}
try {
SerializationConfig config = getSerializationConfig().
without(SerializationFeature.WRAP_ROOT_VALUE);
_serializerProvider(config).serializeValue(buf, overrides);
JsonParser p = buf.asParser();
result = readerForUpdating(valueToUpdate).readValue(p);
p.close();
} catch (IOException e) { // should not occur, no real i/o...
if (e instanceof JsonMappingException) {
throw (JsonMappingException) e;
}
// 17-Mar-2017, tatu: Really ought not happen...
throw JsonMappingException.fromUnexpectedIOE(e);
}
}
return result;
}
/*
/**********************************************************
/* Extended Public API: JSON Schema generation
/**********************************************************
*/
/**
* Generate Json-schema
* instance for specified class.
*
* @param t The class to generate schema for
* @return Constructed JSON schema.
*
* @deprecated Since 2.6 use external JSON Schema generator (https://github.com/FasterXML/jackson-module-jsonSchema)
* (which under the hood calls {@link #acceptJsonFormatVisitor(JavaType, JsonFormatVisitorWrapper)})
*/
@Deprecated
public com.pdd.pop.ext.fasterxml.jackson.databind.jsonschema.JsonSchema generateJsonSchema(Class> t)
throws JsonMappingException {
return _serializerProvider(getSerializationConfig()).generateJsonSchema(t);
}
/**
* Method for visiting type hierarchy for given type, using specified visitor.
*
* This method can be used for things like
* generating JSON Schema
* instance for specified type.
*
* @param type Type to generate schema for (possibly with generic signature)
*
* @since 2.1
*/
public void acceptJsonFormatVisitor(Class> type, JsonFormatVisitorWrapper visitor)
throws JsonMappingException
{
acceptJsonFormatVisitor(_typeFactory.constructType(type), visitor);
}
/**
* Method for visiting type hierarchy for given type, using specified visitor.
* Visitation uses Serializer
hierarchy and related properties
*
* This method can be used for things like
* generating JSON Schema
* instance for specified type.
*
* @param type Type to generate schema for (possibly with generic signature)
*
* @since 2.1
*/
public void acceptJsonFormatVisitor(JavaType type, JsonFormatVisitorWrapper visitor)
throws JsonMappingException
{
if (type == null) {
throw new IllegalArgumentException("type must be provided");
}
_serializerProvider(getSerializationConfig()).acceptJsonFormatVisitor(type, visitor);
}
/*
/**********************************************************
/* Internal methods for serialization, overridable
/**********************************************************
*/
/**
* Overridable helper method used for constructing
* {@link SerializerProvider} to use for serialization.
*/
protected DefaultSerializerProvider _serializerProvider(SerializationConfig config) {
return _serializerProvider.createInstance(config, _serializerFactory);
}
/**
* Method called to configure the generator as necessary and then
* call write functionality
*/
protected final void _configAndWriteValue(JsonGenerator g, Object value)
throws IOException
{
SerializationConfig cfg = getSerializationConfig();
cfg.initialize(g); // since 2.5
if (cfg.isEnabled(SerializationFeature.CLOSE_CLOSEABLE) && (value instanceof Closeable)) {
_configAndWriteCloseable(g, value, cfg);
return;
}
try {
_serializerProvider(cfg).serializeValue(g, value);
} catch (Exception e) {
ClassUtil.closeOnFailAndThrowAsIOE(g, e);
return;
}
g.close();
}
/**
* Helper method used when value to serialize is {@link Closeable} and its close()
* method is to be called right after serialization has been called
*/
private final void _configAndWriteCloseable(JsonGenerator g, Object value, SerializationConfig cfg)
throws IOException
{
Closeable toClose = (Closeable) value;
try {
_serializerProvider(cfg).serializeValue(g, value);
Closeable tmpToClose = toClose;
toClose = null;
tmpToClose.close();
} catch (Exception e) {
ClassUtil.closeOnFailAndThrowAsIOE(g, toClose, e);
return;
}
g.close();
}
/**
* Helper method used when value to serialize is {@link Closeable} and its close()
* method is to be called right after serialization has been called
*/
private final void _writeCloseableValue(JsonGenerator g, Object value, SerializationConfig cfg)
throws IOException
{
Closeable toClose = (Closeable) value;
try {
_serializerProvider(cfg).serializeValue(g, value);
if (cfg.isEnabled(SerializationFeature.FLUSH_AFTER_WRITE_VALUE)) {
g.flush();
}
} catch (Exception e) {
ClassUtil.closeOnFailAndThrowAsIOE(null, toClose, e);
return;
}
toClose.close();
}
/*
/**********************************************************
/* Internal methods for deserialization, overridable
/**********************************************************
*/
/**
* Actual implementation of value reading+binding operation.
*/
protected Object _readValue(DeserializationConfig cfg, JsonParser p,
JavaType valueType)
throws IOException
{
/* First: may need to read the next token, to initialize
* state (either before first read from parser, or after
* previous token has been cleared)
*/
Object result;
JsonToken t = _initForReading(p, valueType);
final DeserializationContext ctxt = createDeserializationContext(p, cfg);
if (t == JsonToken.VALUE_NULL) {
// Ask JsonDeserializer what 'null value' to use:
result = _findRootDeserializer(ctxt, valueType).getNullValue(ctxt);
} else if (t == JsonToken.END_ARRAY || t == JsonToken.END_OBJECT) {
result = null;
} else { // pointing to event other than null
JsonDeserializer deser = _findRootDeserializer(ctxt, valueType);
// ok, let's get the value
if (cfg.useRootWrapping()) {
result = _unwrapAndDeserialize(p, ctxt, cfg, valueType, deser);
} else {
result = deser.deserialize(p, ctxt);
}
}
// Need to consume the token too
p.clearCurrentToken();
if (cfg.isEnabled(DeserializationFeature.FAIL_ON_TRAILING_TOKENS)) {
_verifyNoTrailingTokens(p, ctxt, valueType);
}
return result;
}
protected Object _readMapAndClose(JsonParser p0, JavaType valueType)
throws IOException
{
try (JsonParser p = p0) {
Object result;
JsonToken t = _initForReading(p, valueType);
final DeserializationConfig cfg = getDeserializationConfig();
final DeserializationContext ctxt = createDeserializationContext(p, cfg);
if (t == JsonToken.VALUE_NULL) {
// Ask JsonDeserializer what 'null value' to use:
result = _findRootDeserializer(ctxt, valueType).getNullValue(ctxt);
} else if (t == JsonToken.END_ARRAY || t == JsonToken.END_OBJECT) {
result = null;
} else {
JsonDeserializer deser = _findRootDeserializer(ctxt, valueType);
if (cfg.useRootWrapping()) {
result = _unwrapAndDeserialize(p, ctxt, cfg, valueType, deser);
} else {
result = deser.deserialize(p, ctxt);
}
ctxt.checkUnresolvedObjectId();
}
if (cfg.isEnabled(DeserializationFeature.FAIL_ON_TRAILING_TOKENS)) {
_verifyNoTrailingTokens(p, ctxt, valueType);
}
return result;
}
}
/**
* Similar to {@link #_readMapAndClose} but specialized for JsonNode
* reading.
*
* @since 2.9
*/
protected JsonNode _readTreeAndClose(JsonParser p0) throws IOException
{
try (JsonParser p = p0) {
final JavaType valueType = JSON_NODE_TYPE;
DeserializationConfig cfg = getDeserializationConfig();
// 27-Oct-2016, tatu: Need to inline `_initForReading()` due to
// special requirements by tree reading (no fail on eof)
cfg.initialize(p); // since 2.5
JsonToken t = p.getCurrentToken();
if (t == null) {
t = p.nextToken();
if (t == null) { // [databind#1406]: expose end-of-input as `null`
return null;
}
}
if (t == JsonToken.VALUE_NULL) {
return cfg.getNodeFactory().nullNode();
}
DeserializationContext ctxt = createDeserializationContext(p, cfg);
JsonDeserializer deser = _findRootDeserializer(ctxt, valueType);
Object result;
if (cfg.useRootWrapping()) {
result = _unwrapAndDeserialize(p, ctxt, cfg, valueType, deser);
} else {
result = deser.deserialize(p, ctxt);
if (cfg.isEnabled(DeserializationFeature.FAIL_ON_TRAILING_TOKENS)) {
_verifyNoTrailingTokens(p, ctxt, valueType);
}
}
// No ObjectIds so can ignore
// ctxt.checkUnresolvedObjectId();
return (JsonNode) result;
}
}
protected Object _unwrapAndDeserialize(JsonParser p, DeserializationContext ctxt,
DeserializationConfig config,
JavaType rootType, JsonDeserializer deser)
throws IOException
{
PropertyName expRootName = config.findRootName(rootType);
// 12-Jun-2015, tatu: Should try to support namespaces etc but...
String expSimpleName = expRootName.getSimpleName();
if (p.getCurrentToken() != JsonToken.START_OBJECT) {
ctxt.reportWrongTokenException(rootType, JsonToken.START_OBJECT,
"Current token not START_OBJECT (needed to unwrap root name '%s'), but %s",
expSimpleName, p.getCurrentToken());
}
if (p.nextToken() != JsonToken.FIELD_NAME) {
ctxt.reportWrongTokenException(rootType, JsonToken.FIELD_NAME,
"Current token not FIELD_NAME (to contain expected root name '%s'), but %s",
expSimpleName, p.getCurrentToken());
}
String actualName = p.getCurrentName();
if (!expSimpleName.equals(actualName)) {
ctxt.reportInputMismatch(rootType,
"Root name '%s' does not match expected ('%s') for type %s",
actualName, expSimpleName, rootType);
}
// ok, then move to value itself....
p.nextToken();
Object result = deser.deserialize(p, ctxt);
// and last, verify that we now get matching END_OBJECT
if (p.nextToken() != JsonToken.END_OBJECT) {
ctxt.reportWrongTokenException(rootType, JsonToken.END_OBJECT,
"Current token not END_OBJECT (to match wrapper object with root name '%s'), but %s",
expSimpleName, p.getCurrentToken());
}
if (config.isEnabled(DeserializationFeature.FAIL_ON_TRAILING_TOKENS)) {
_verifyNoTrailingTokens(p, ctxt, rootType);
}
return result;
}
/**
* Internal helper method called to create an instance of {@link DeserializationContext}
* for deserializing a single root value.
* Can be overridden if a custom context is needed.
*/
protected DefaultDeserializationContext createDeserializationContext(JsonParser p,
DeserializationConfig cfg) {
return _deserializationContext.createInstance(cfg, p, _injectableValues);
}
/**
* Method called to ensure that given parser is ready for reading
* content for data binding.
*
* @return First token to be used for data binding after this call:
* can never be null as exception will be thrown if parser cannot
* provide more tokens.
*
* @throws IOException if the underlying input source has problems during
* parsing
* @throws JsonParseException if parser has problems parsing content
* @throws JsonMappingException if the parser does not have any more
* content to map (note: Json "null" value is considered content;
* enf-of-stream not)
*/
protected JsonToken _initForReading(JsonParser p, JavaType targetType) throws IOException
{
_deserializationConfig.initialize(p); // since 2.5
// First: must point to a token; if not pointing to one, advance.
// This occurs before first read from JsonParser, as well as
// after clearing of current token.
JsonToken t = p.getCurrentToken();
if (t == null) {
// and then we must get something...
t = p.nextToken();
if (t == null) {
// Throw mapping exception, since it's failure to map,
// not an actual parsing problem
throw MismatchedInputException.from(p, targetType,
"No content to map due to end-of-input");
}
}
return t;
}
@Deprecated // since 2.9, use method that takes JavaType too
protected JsonToken _initForReading(JsonParser p) throws IOException {
return _initForReading(p, null);
}
/**
* @since 2.9
*/
protected final void _verifyNoTrailingTokens(JsonParser p, DeserializationContext ctxt,
JavaType bindType)
throws IOException
{
JsonToken t = p.nextToken();
if (t != null) {
Class> bt = ClassUtil.rawClass(bindType);
ctxt.reportTrailingTokens(bt, p, t);
}
}
/*
/**********************************************************
/* Internal methods, other
/**********************************************************
*/
/**
* Method called to locate deserializer for the passed root-level value.
*/
protected JsonDeserializer _findRootDeserializer(DeserializationContext ctxt,
JavaType valueType)
throws JsonMappingException
{
// First: have we already seen it?
JsonDeserializer deser = _rootDeserializers.get(valueType);
if (deser != null) {
return deser;
}
// Nope: need to ask provider to resolve it
deser = ctxt.findRootValueDeserializer(valueType);
if (deser == null) { // can this happen?
return ctxt.reportBadDefinition(valueType,
"Cannot find a deserializer for type "+valueType);
}
_rootDeserializers.put(valueType, deser);
return deser;
}
/**
* @since 2.2
*/
protected void _verifySchemaType(FormatSchema schema)
{
if (schema != null) {
if (!_jsonFactory.canUseSchema(schema)) {
throw new IllegalArgumentException("Cannot use FormatSchema of type "+schema.getClass().getName()
+" for format "+_jsonFactory.getFormatName());
}
}
}
}