![JAR search and dependency download from the Maven repository](/logo.png)
org.codehaus.jackson.map.ObjectMapper Maven / Gradle / Ivy
package org.codehaus.jackson.map;
import java.io.*;
import java.net.URL;
import java.util.concurrent.ConcurrentHashMap;
import org.codehaus.jackson.*;
import org.codehaus.jackson.io.SegmentedStringWriter;
import org.codehaus.jackson.map.deser.StdDeserializationContext;
import org.codehaus.jackson.map.deser.StdDeserializerProvider;
import org.codehaus.jackson.map.introspect.BasicClassIntrospector;
import org.codehaus.jackson.map.introspect.JacksonAnnotationIntrospector;
import org.codehaus.jackson.map.ser.StdSerializerProvider;
import org.codehaus.jackson.map.ser.BeanSerializerFactory;
import org.codehaus.jackson.map.type.TypeFactory;
import org.codehaus.jackson.node.ArrayNode;
import org.codehaus.jackson.node.JsonNodeFactory;
import org.codehaus.jackson.node.TreeTraversingParser;
import org.codehaus.jackson.node.NullNode;
import org.codehaus.jackson.node.ObjectNode;
import org.codehaus.jackson.schema.JsonSchema;
import org.codehaus.jackson.type.JavaType;
import org.codehaus.jackson.type.TypeReference;
/**
* This mapper (or, data binder, or codec) provides functionality for
* conversting between Java objects (instances of JDK provided core classes,
* beans), and matching JSON constructs.
* It will use instances of {@link JsonParser} and {@link JsonGenerator}
* for implementing actual reading/writing of JSON.
*
* The main conversion API is defined in {@link ObjectCodec}, so that
* implementation details of this class need not be exposed to
* streaming parser and generator classes.
*
* Note on caching: root-level deserializers are always cached, and accessed
* using full (generics-aware) type information. This is different from
* caching of referenced types, which is more limited and is done only
* for a subset of all deserializer types. The main reason for difference
* is that at root-level there is no incoming reference (and hence no
* referencing property, no referral information or annotations to
* produce differing deserializers), and that the performance impact
* greatest at root level (since it'll essentially cache the full
* graph of deserializers involved).
*/
public class ObjectMapper
extends ObjectCodec
{
final static JavaType JSON_NODE_TYPE = TypeFactory.type(JsonNode.class);
/* !!! 03-Apr-2009, tatu: Should try to avoid direct reference... but not
* sure what'd be simple and elegant way. So until then:
*/
protected final static ClassIntrospector extends BeanDescription> DEFAULT_INTROSPECTOR = BasicClassIntrospector.instance;
// 16-May-2009, tatu: Ditto ^^^
protected final static AnnotationIntrospector DEFAULT_ANNOTATION_INTROSPECTOR = new JacksonAnnotationIntrospector();
/*
////////////////////////////////////////////////////
// Configuration settings, shared
////////////////////////////////////////////////////
*/
/**
* Factory used to create {@link JsonParser} and {@link JsonGenerator}
* instances as necessary.
*/
protected final JsonFactory _jsonFactory;
/*
////////////////////////////////////////////////////
// Configuration settings, serialization
////////////////////////////////////////////////////
*/
/**
* Configuration object that defines basic global
* settings for the serialization process
*/
protected SerializationConfig _serializationConfig;
/**
* Object that manages access to serializers used for serialization,
* including caching.
* It is configured with {@link #_serializerFactory} to allow
* for constructing custom serializers.
*/
protected SerializerProvider _serializerProvider;
/**
* Serializer factory used for constructing serializers.
*/
protected SerializerFactory _serializerFactory;
/*
////////////////////////////////////////////////////
// Configuration settings, deserialization
////////////////////////////////////////////////////
*/
/**
* Configuration object that defines basic global
* settings for the serialization process
*/
protected DeserializationConfig _deserializationConfig;
/**
* Object that manages access to deserializers used for deserializing
* JSON content into Java objects, including possible caching
* of the deserializers. It contains a reference to
* {@link DeserializerFactory} to use for constructing acutal deserializers.
*/
protected DeserializerProvider _deserializerProvider;
/*
////////////////////////////////////////////////////
// Configuration settings, other
////////////////////////////////////////////////////
*/
/**
* Node factory to use for creating
*
* @since 1.2
*/
protected JsonNodeFactory _nodeFactory;
/*
////////////////////////////////////////////////////
// Caching
////////////////////////////////////////////////////
*/
/* Note: handling of serializers and deserializers is not symmetric;
* and as a result, only root-level deserializers can be cached here.
* This is mostly because typing and resolution for deserializers is
* fully static; whereas it is quite dynamic for serialization.
*/
/**
* We will use a separate main-level Map for keeping track
* of root-level deserializers. This is where most succesful
* cache lookups get resolved.
* Map will contain resolvers for all kinds of types, including
* container types: this is different from the component cache
* which will only cache bean deserializers.
*
* Given that we don't expect much concurrency for additions
* (should very quickly converge to zero after startup), let's
* explicitly define a low concurrency setting.
*/
final protected ConcurrentHashMap> _rootDeserializers
= new ConcurrentHashMap>(64, 0.6f, 2);
/*
////////////////////////////////////////////////////
// Life-cycle (construction, configuration)
////////////////////////////////////////////////////
*/
/**
* Default constructor, which will construct the default
* {@link JsonFactory} as necessary, use
* {@link StdSerializerProvider} as its
* {@link SerializerProvider}, and
* {@link BeanSerializerFactory} as its
* {@link SerializerFactory}.
* This means that it
* can serialize all standard JDK types, as well as regular
* Java Beans (based on method names and Jackson-specific annotations),
* but does not support JAXB annotations.
*/
public ObjectMapper()
{
this(null, null, null);
}
/**
* Construct mapper that uses specified {@link JsonFactory}
* for constructing necessary {@link JsonParser}s and/or
* {@link JsonGenerator}s.
*/
public ObjectMapper(JsonFactory jf)
{
this(jf, null, null);
}
/**
* Construct mapper that uses specified {@link SerializerFactory}
* for constructing necessary serializers.
*
* @deprecated Use other constructors instead; note that
* you can just set serializer factory with {@link #setSerializerFactory}
*/
public ObjectMapper(SerializerFactory sf)
{
this(null, null, null);
setSerializerFactory(sf);
}
public ObjectMapper(JsonFactory jf,
SerializerProvider sp, DeserializerProvider dp)
{
this(jf, sp, dp, null, null);
}
/**
*
* @param jf JsonFactory to use: if null, a new {@link MappingJsonFactory} will be constructed
* @param sp SerializerProvider to use: if null, a {@link StdSerializerProvider} will be constructed
* @param dp DeserializerProvider to use: if null, a {@link StdDeserializerProvider} will be constructed
* @param sconfig Serialization configuration to use; if null, basic {@link SerializationConfig}
* will be constructed
* @param dconfig Deserialization configuration to use; if null, basic {@link DeserializationConfig}
* will be constructed
*/
public ObjectMapper(JsonFactory jf,
SerializerProvider sp, DeserializerProvider dp,
SerializationConfig sconfig, DeserializationConfig dconfig)
{
/* 02-Mar-2009, tatu: Important: we MUST default to using
* the mapping factory, otherwise tree serialization will
* have problems with POJONodes.
* 03-Jan-2010, tatu: and obviously we also must pass 'this',
* to create actual linking.
*/
_jsonFactory = (jf == null) ? new MappingJsonFactory(this) : jf;
_serializationConfig = (sconfig == null) ? new SerializationConfig(DEFAULT_INTROSPECTOR, DEFAULT_ANNOTATION_INTROSPECTOR) : sconfig;
_deserializationConfig = (dconfig == null) ? new DeserializationConfig(DEFAULT_INTROSPECTOR, DEFAULT_ANNOTATION_INTROSPECTOR) : dconfig;
_serializerProvider = (sp == null) ? new StdSerializerProvider() : sp;
_deserializerProvider = (dp == null) ? new StdDeserializerProvider() : dp;
// Default serializer factory is stateless, can just assign
_serializerFactory = BeanSerializerFactory.instance;
// and use standard JsonNodeFactory initially
_nodeFactory = JsonNodeFactory.instance;
}
/**
* Method for setting specific {@link SerializerFactory} to use
* for constructing (bean) serializers.
*/
public ObjectMapper setSerializerFactory(SerializerFactory f) {
_serializerFactory = f;
return this;
}
/**
* Method for setting specific {@link SerializerProvider} to use
* for handling caching of {@link JsonSerializer} instances.
*/
public ObjectMapper setSerializerProvider(SerializerProvider p) {
_serializerProvider = p;
return this;
}
/**
* @since 1.4
*/
public SerializerProvider getSerializerProvider() {
return _serializerProvider;
}
/**
* Method for setting specific {@link DeserializerProvider} to use
* for handling caching of {@link JsonDeserializer} instances.
*/
public ObjectMapper setDeserializerProvider(DeserializerProvider p) {
_deserializerProvider = p;
return this;
}
/**
* @since 1.4
*/
public DeserializerProvider getDeserializerProvider() {
return _deserializerProvider;
}
/**
* Method for specifying {@link JsonNodeFactory} to use for
* constructing root level tree nodes (via method
* {@link #createObjectNode}
*
* @since 1.2
*/
public ObjectMapper setNodeFactory(JsonNodeFactory f) {
_nodeFactory = f;
return this;
}
/*
////////////////////////////////////////////////////
// Access to configuration settings
////////////////////////////////////////////////////
*/
/**
* Method that returns
* the shared default {@link SerializationConfig} object
* that defines configuration settings for serialization.
* Returned object is "live" meaning that changes will be used
* for future serialization operations for this mapper when using
* mapper's default configuration
*/
public SerializationConfig getSerializationConfig() {
return _serializationConfig;
}
/**
* Method that creates a copy of
* the shared default {@link SerializationConfig} object
* that defines configuration settings for serialization.
* Since it is a copy, any changes made to the configuration
* object will NOT directly affect serialization done using
* basic serialization methods that use the shared object (that is,
* ones that do not take separate {@link SerializationConfig}
* argument.
*
* The use case is that of changing object settings of the configuration
* (like date format being used, see {@link SerializationConfig#setDateFormat}).
*/
public SerializationConfig copySerializationConfig() {
return _serializationConfig.createUnshared();
}
/**
* Method for replacing the shared default serialization configuration
* object.
*/
public ObjectMapper setSerializationConfig(SerializationConfig cfg) {
_serializationConfig = cfg;
return this;
}
/**
* Method for changing state of an on/off serialization feature for
* this object mapper.
*
* This is method is basically a shortcut method for calling
* {@link SerializationConfig#set} on the shared {@link SerializationConfig}
* object with given arguments.
*/
public ObjectMapper configure(SerializationConfig.Feature f, boolean state) {
_serializationConfig.set(f, state);
return this;
}
/**
* Method that returns
* the shared default {@link DeserializationConfig} object
* that defines configuration settings for deserialization.
* Returned object is "live" meaning that changes will be used
* for future deserialization operations for this mapper when using
* mapper's default configuration
*/
public DeserializationConfig getDeserializationConfig() {
return _deserializationConfig;
}
/**
* Method that creates a copy of
* the shared default {@link DeserializationConfig} object
* that defines configuration settings for deserialization.
* Since it is a copy, any changes made to the configuration
* object will NOT directly affect deserialization done using
* basic deserialization methods that use the shared object (that is,
* ones that do not take separate {@link DeserializationConfig}
* argument.
*
* The use case is that of changing object settings of the configuration
* (like deserialization problem handler,
* see {@link DeserializationConfig#addHandler})
*/
public DeserializationConfig copyDeserializationConfig() {
return _deserializationConfig.createUnshared();
}
/**
* Method for replacing the shared default deserialization configuration
* object.
*/
public ObjectMapper setDeserializationConfig(DeserializationConfig cfg) {
_deserializationConfig = cfg;
return this;
}
/**
* Method for changing state of an on/off deserialization feature for
* this object mapper.
*
* This is method is basically a shortcut method for calling
* {@link DeserializationConfig#set} on the shared {@link DeserializationConfig}
* object with given arguments.
*/
public ObjectMapper configure(DeserializationConfig.Feature f, boolean state) {
_deserializationConfig.set(f, state);
return this;
}
/**
* 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.
*
* @return {@link JsonFactory} that this mapper uses when it needs to
* construct Json parser and generators
*/
public JsonFactory getJsonFactory() { return _jsonFactory; }
/**
* Method for changing state of an on/off {@link JsonParser} feature for
* {@link JsonFactory} instance this object mapper uses.
*
* This is method is basically a shortcut method for calling
* {@link JsonFactory#setParserFeature} on the shared
* {@link JsonFactory} this mapper uses (which is accessible
* using {@link #getJsonFactory}).
*
* @since 1.2
*/
public ObjectMapper configure(JsonParser.Feature f, boolean state) {
_jsonFactory.configure(f, state);
return this;
}
/**
* Method for changing state of an on/off {@link JsonGenerator} feature for
* {@link JsonFactory} instance this object mapper uses.
*
* This is method is basically a shortcut method for calling
* {@link JsonFactory#setGeneratorFeature} on the shared
* {@link JsonFactory} this mapper uses (which is accessible
* using {@link #getJsonFactory}).
*
* @since 1.2
*/
public ObjectMapper configure(JsonGenerator.Feature f, boolean state) {
_jsonFactory.configure(f, state);
return this;
}
/**
* 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.
*
* @since 1.2
*/
public JsonNodeFactory getNodeFactory() {
return _nodeFactory;
}
/*
////////////////////////////////////////////////////
// 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
* can not be introspected when using this method.
*/
@Override
@SuppressWarnings("unchecked")
public T readValue(JsonParser jp, Class valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readValue(jp, TypeFactory.type(valueType), copyDeserializationConfig());
}
/**
* 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
* can not be introspected when using this method.
* @since 1.1
*
* @param cfg Specific deserialization configuration to use for
* this operation. Note that not all config settings can
* be changed on per-operation basis: some changeds only take effect
* before calling the operation for the first time (for the mapper
* instance)
*/
@SuppressWarnings("unchecked")
public T readValue(JsonParser jp, Class valueType,
DeserializationConfig cfg)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readValue(jp, TypeFactory.type(valueType), cfg);
}
/**
* 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.
*/
@Override
@SuppressWarnings("unchecked")
public T readValue(JsonParser jp, TypeReference> valueTypeRef)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readValue(jp, TypeFactory.type(valueTypeRef),
copyDeserializationConfig());
}
/**
* 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.
*
* @param cfg Specific deserialization configuration to use for
* this operation. Note that not all config settings can
* be changed on per-operation basis: some changeds only take effect
* before calling the operation for the first time (for the mapper
* instance)
*
* @since 1.1
*/
@SuppressWarnings("unchecked")
public T readValue(JsonParser jp, TypeReference> valueTypeRef,
DeserializationConfig cfg)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readValue(jp, TypeFactory.type(valueTypeRef), cfg);
}
/**
* 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}.
*/
@Override
@SuppressWarnings("unchecked")
public T readValue(JsonParser jp, JavaType valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readValue(jp, valueType, copyDeserializationConfig());
}
/**
* 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}.
*
* @param cfg Specific deserialization configuration to use for
* this operation. Note that not all config settings can
* be changed on per-operation basis: some changeds only take effect
* before calling the operation for the first time (for the mapper
* instance)
*
* @since 1.1
*/
@SuppressWarnings("unchecked")
public T readValue(JsonParser jp, JavaType valueType,
DeserializationConfig cfg)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readValue(jp, valueType, cfg);
}
/**
* 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).
*/
@Override
public JsonNode readTree(JsonParser jp)
throws IOException, JsonProcessingException
{
return readTree(jp, copyDeserializationConfig());
}
/**
* 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 cfg Specific deserialization configuration to use for
* this operation. Note that not all config settings can
* be changed on per-operation basis: some changeds only take effect
* before calling the operation for the first time (for the mapper
* instance)
*
* @since 1.1
*/
public JsonNode readTree(JsonParser jp, DeserializationConfig cfg)
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.
*/
JsonNode n = (JsonNode) _readValue(jp, JSON_NODE_TYPE, cfg);
return (n == null) ? NullNode.instance : n;
}
/**
* 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 in Input stream used to read JSON content
* for building the JSON tree.
*
* @since 1.3
*/
public JsonNode readTree(InputStream in)
throws IOException, JsonProcessingException
{
JsonNode n = (JsonNode) readValue(in, JSON_NODE_TYPE);
return (n == null) ? NullNode.instance : n;
}
/**
* 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 r Reader used to read JSON content
* for building the JSON tree.
*
* @since 1.3
*/
public JsonNode readTree(Reader r)
throws IOException, JsonProcessingException
{
JsonNode n = (JsonNode) readValue(r, JSON_NODE_TYPE);
return (n == null) ? NullNode.instance : n;
}
/**
* 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
* for building the JSON tree.
*
* @since 1.3
*/
public JsonNode readTree(String content)
throws IOException, JsonProcessingException
{
JsonNode n = (JsonNode) readValue(content, JSON_NODE_TYPE);
return (n == null) ? NullNode.instance : n;
}
/*
////////////////////////////////////////////////////
// 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 jgen, Object value)
throws IOException, JsonGenerationException, JsonMappingException
{
_serializerProvider.serializeValue(copySerializationConfig(), jgen, value, _serializerFactory);
jgen.flush();
}
/**
* Method that can be used to serialize any Java value as
* Json output, using provided {@link JsonGenerator},
* configured as per passed configuration object.
*
* @since 1.1
*/
public void writeValue(JsonGenerator jgen, Object value, SerializationConfig config)
throws IOException, JsonGenerationException, JsonMappingException
{
_serializerProvider.serializeValue(config, jgen, value, _serializerFactory);
jgen.flush();
}
/**
* Method to serialize given Json Tree, using generator
* provided.
*/
public void writeTree(JsonGenerator jgen, JsonNode rootNode)
throws IOException, JsonProcessingException
{
_serializerProvider.serializeValue(copySerializationConfig(), jgen, rootNode, _serializerFactory);
jgen.flush();
}
/**
* Method to serialize given Json Tree, using generator
* provided.
*
* @since 1.1
*/
public void writeTree(JsonGenerator jgen, JsonNode rootNode,
SerializationConfig cfg)
throws IOException, JsonProcessingException
{
_serializerProvider.serializeValue(cfg, jgen, rootNode, _serializerFactory);
jgen.flush();
}
/*
////////////////////////////////////////////////////
// Public API (from ObjectCodec): Tree Model support
////////////////////////////////////////////////////
*/
/**
*
* Note: return type is co-variant, as basic ObjectCodec
* abstraction can not refer to concrete node types (as it's
* part of core package, whereas impls are part of mapper
* package)
*
* @since 1.2
*/
public ObjectNode createObjectNode() {
return _nodeFactory.objectNode();
}
/**
*
* Note: return type is co-variant, as basic ObjectCodec
* abstraction can not refer to concrete node types (as it's
* part of core package, whereas impls are part of mapper
* package)
*
* @since 1.2
*/
public ArrayNode createArrayNode() {
return _nodeFactory.arrayNode();
}
/**
* @since 1.3
*/
public JsonParser treeAsTokens(JsonNode n)
{
return new TreeTraversingParser(n, this);
}
/*
* @since 1.3
*
public JsonGenerator treeFromTokens(JsonNode n)
{
if (!n.isContainerNode()) {
throw new IllegalArgumentException("JsonNode passed in is not a container node (type "+n.getClass().getName()+")");
}
return new TreeAppendingGenerator((ContainerNode) n, this);
}
*/
public T treeToValue(JsonNode n, Class valueType)
throws IOException, JsonParseException, JsonMappingException
{
JsonParser jp = treeAsTokens(n);
return readValue(jp, valueType);
}
/*
////////////////////////////////////////////////////
// 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.
*
* @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.hasSerializerFor(_serializationConfig, type, _serializerFactory);
}
/**
* 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 deserializer can be found for the type.
*
* @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 _deserializerProvider.hasValueDeserializerFor(_deserializationConfig, type);
}
/*
////////////////////////////////////////////////////
// Extended Public API, deserialization,
// convenience methods
////////////////////////////////////////////////////
*/
@SuppressWarnings("unchecked")
public T readValue(File src, Class valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createJsonParser(src), TypeFactory.type(valueType));
}
@SuppressWarnings("unchecked")
public T readValue(File src, TypeReference valueTypeRef)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createJsonParser(src), TypeFactory.type(valueTypeRef));
}
@SuppressWarnings("unchecked")
public T readValue(File src, JavaType valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createJsonParser(src), valueType);
}
@SuppressWarnings("unchecked")
public T readValue(URL src, Class valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createJsonParser(src), TypeFactory.type(valueType));
}
@SuppressWarnings("unchecked")
public T readValue(URL src, TypeReference valueTypeRef)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createJsonParser(src), TypeFactory.type(valueTypeRef));
}
@SuppressWarnings("unchecked")
public T readValue(URL src, JavaType valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createJsonParser(src), valueType);
}
@SuppressWarnings("unchecked")
public T readValue(String content, Class valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createJsonParser(content), TypeFactory.type(valueType));
}
@SuppressWarnings("unchecked")
public T readValue(String content, TypeReference valueTypeRef)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createJsonParser(content), TypeFactory.type(valueTypeRef));
}
@SuppressWarnings("unchecked")
public T readValue(String content, JavaType valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createJsonParser(content), valueType);
}
@SuppressWarnings("unchecked")
public T readValue(Reader src, Class valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createJsonParser(src), TypeFactory.type(valueType));
}
@SuppressWarnings("unchecked")
public T readValue(Reader src, TypeReference valueTypeRef)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createJsonParser(src), TypeFactory.type(valueTypeRef));
}
@SuppressWarnings("unchecked")
public T readValue(Reader src, JavaType valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createJsonParser(src), valueType);
}
@SuppressWarnings("unchecked")
public T readValue(InputStream src, Class valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createJsonParser(src), TypeFactory.type(valueType));
}
@SuppressWarnings("unchecked")
public T readValue(InputStream src, TypeReference valueTypeRef)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createJsonParser(src), TypeFactory.type(valueTypeRef));
}
@SuppressWarnings("unchecked")
public T readValue(InputStream src, JavaType valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createJsonParser(src), valueType);
}
@SuppressWarnings("unchecked")
public T readValue(byte[] src, int offset, int len,
Class valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createJsonParser(src, offset, len), TypeFactory.type(valueType));
}
@SuppressWarnings("unchecked")
public T readValue(byte[] src, int offset, int len,
TypeReference valueTypeRef)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createJsonParser(src, offset, len), TypeFactory.type(valueTypeRef));
}
@SuppressWarnings("unchecked")
public T readValue(byte[] src, int offset, int len,
JavaType valueType)
throws IOException, JsonParseException, JsonMappingException
{
return (T) _readMapAndClose(_jsonFactory.createJsonParser(src, offset, len), 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.createJsonGenerator(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.createJsonGenerator(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.createJsonGenerator(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.
*
* @since 1.3
*/
public String writeValueAsString(Object value)
throws IOException, JsonGenerationException, JsonMappingException
{
// alas, we have to pull the recycler directly here...
SegmentedStringWriter sw = new SegmentedStringWriter(_jsonFactory._getBufferRecycler());
_configAndWriteValue(_jsonFactory.createJsonGenerator(sw), value);
return sw.getAndClear();
}
/*
////////////////////////////////////////////////////
// Extended Public API: serialization using Json Views
////////////////////////////////////////////////////
*/
/**
* Method for serializing given object using specified view.
* Note that this method is essentially just a shortcut: view to use is
* by {@link SerializationConfig} and so this method just assigns
* given view to a copy of default configuration of this
* mapper. So to use other kinds of destinations, just call
* {@link #copySerializationConfig}, call
* {@link SerializationConfig#setSerializationView} method on it,
* and pass that configuration to other methods.
*
* @param jgen Generator to use for writing JSON content
* @param value Value to serialize
* @param viewClass (optional) Identifier for View to use. If null,
* equivalent to passing Object.class
; both of which
* mean "default view" (all properties always included)
*/
public void writeValueUsingView(JsonGenerator jgen, Object value, Class> viewClass)
throws IOException, JsonGenerationException, JsonMappingException
{
_configAndWriteValue(jgen, value, viewClass);
}
/**
* Method for serializing given object using specified view.
* As with {@link #writeValueUsingView(JsonGenerator,Object,Class)},
* this is a short-cut method.
*
* @param w Writer used for writing JSON content
* @param value Value to serialize
* @param viewClass (optional) Identifier for View to use. If null,
* equivalent to passing Object.class
; both of which
* mean "default view" (all properties always included)
*/
public void writeValueUsingView(Writer w, Object value, Class> viewClass)
throws IOException, JsonGenerationException, JsonMappingException
{
_configAndWriteValue(_jsonFactory.createJsonGenerator(w), value, viewClass);
}
/**
* Method for serializing given object using specified view.
* As with {@link #writeValueUsingView(JsonGenerator,Object,Class)},
* this is a short-cut method.
*
* @param out Output stream used for writing JSON content
* @param value Value to serialize
* @param viewClass (optional) Identifier for View to use. If null,
* equivalent to passing Object.class
; both of which
* mean "default view" (all properties always included)
*/
public void writeValueUsingView(OutputStream out, Object value, Class> viewClass)
throws IOException, JsonGenerationException, JsonMappingException
{
_configAndWriteValue(_jsonFactory.createJsonGenerator(out, JsonEncoding.UTF8), value, viewClass);
}
/*
////////////////////////////////////////////////////
// Extended Public API: convenience type conversion
////////////////////////////////////////////////////
*/
/**
* Convenience method for doing two-step conversion from given value, into
* instance of given value type. This is functionality equivalent to first
* serializing given value into JSON, then binding JSON data into value
* of given type, but may be executed without fully serializing into
* JSON. Same converters (serializers, deserializers) will be used as for
* data binding, meaning same object mapper configuration works.
*
* @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.type(toValueType));
}
@SuppressWarnings("unchecked")
public T convertValue(Object fromValue, TypeReference toValueTypeRef)
throws IllegalArgumentException
{
return (T) _convert(fromValue, TypeFactory.type(toValueTypeRef));
}
@SuppressWarnings("unchecked")
public T convertValue(Object fromValue, JavaType toValueType)
throws IllegalArgumentException
{
return (T) _convert(fromValue, toValueType);
}
protected Object _convert(Object fromValue, JavaType toValueType)
throws IllegalArgumentException
{
// sanity check for null first:
if (fromValue == null) return null;
try {
/* TODO: [JACKSON-175], use an intermediate token buffer
*/
ByteArrayOutputStream bos = new ByteArrayOutputStream(200);
writeValue(bos, fromValue);
byte[] data = bos.toByteArray();
return readValue(data, 0, data.length, toValueType);
} catch (IOException e) {
throw new IllegalArgumentException(e.getMessage(), e);
}
}
/*
////////////////////////////////////////////////////
// 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.
*/
public JsonSchema generateJsonSchema(Class> t)
throws JsonMappingException
{
return generateJsonSchema(t, copySerializationConfig());
}
/**
* Generate Json-schema
* instance for specified class, using specific
* serialization configuration
*
* @param t The class to generate schema for
* @return Constructed JSON schema.
*/
public JsonSchema generateJsonSchema(Class> t, SerializationConfig cfg)
throws JsonMappingException
{
return _serializerProvider.generateJsonSchema(t, cfg, _serializerFactory);
}
/*
////////////////////////////////////////////////////
// Internal methods, overridable
////////////////////////////////////////////////////
*/
/**
* Method called to configure the generator as necessary and then
* call write functionality
*/
protected final void _configAndWriteValue(JsonGenerator jgen, Object value)
throws IOException, JsonGenerationException, JsonMappingException
{
SerializationConfig cfg = copySerializationConfig();
// [JACKSON-96]: allow enabling pretty printing for ObjectMapper directly
if (cfg.isEnabled(SerializationConfig.Feature.INDENT_OUTPUT)) {
jgen.useDefaultPrettyPrinter();
}
boolean closed = false;
try {
_serializerProvider.serializeValue(cfg, jgen, value, _serializerFactory);
closed = true;
jgen.close();
} finally {
/* won't try to close twice; also, must catch exception (so it
* will not mask exception that is pending)
*/
if (!closed) {
try {
jgen.close();
} catch (IOException ioe) { }
}
}
}
protected final void _configAndWriteValue(JsonGenerator jgen, Object value, Class> viewClass)
throws IOException, JsonGenerationException, JsonMappingException
{
SerializationConfig cfg = copySerializationConfig();
if (cfg.isEnabled(SerializationConfig.Feature.INDENT_OUTPUT)) {
jgen.useDefaultPrettyPrinter();
}
cfg.setSerializationView(viewClass);
boolean closed = false;
try {
_serializerProvider.serializeValue(cfg, jgen, value, _serializerFactory);
closed = true;
jgen.close();
} finally {
if (!closed) {
try {
jgen.close();
} catch (IOException ioe) { }
}
}
}
/**
* Actual implementation of value reading+binding operation.
*/
protected Object _readValue(JsonParser jp, JavaType valueType,
DeserializationConfig cfg)
throws IOException, JsonParseException, JsonMappingException
{
/* 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(jp);
if (t == JsonToken.VALUE_NULL
|| t == JsonToken.END_ARRAY
|| t == JsonToken.END_OBJECT) {
result = null;
} else { // pointing to event other than null
DeserializationContext ctxt = _createDeserializationContext(jp, cfg);
// ok, let's get the value
result = _findRootDeserializer(valueType).deserialize(jp, ctxt);
}
// Need to consume the token too
jp.clearCurrentToken();
return result;
}
protected Object _readMapAndClose(JsonParser jp, JavaType valueType)
throws IOException, JsonParseException, JsonMappingException
{
try {
Object result;
JsonToken t = _initForReading(jp);
if (t == JsonToken.VALUE_NULL
|| t == JsonToken.END_ARRAY
|| t == JsonToken.END_OBJECT) {
result = null;
} else {
DeserializationContext ctxt = _createDeserializationContext(jp, copyDeserializationConfig());
result = _findRootDeserializer(valueType).deserialize(jp, ctxt);
}
// Need to consume the token too
jp.clearCurrentToken();
return result;
} finally {
try {
jp.close();
} catch (IOException ioe) { }
}
}
/**
* 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 can not
* 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 jp)
throws IOException, JsonParseException, JsonMappingException
{
/* 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 = jp.getCurrentToken();
if (t == null) {
// and then we must get something...
t = jp.nextToken();
if (t == null) {
/* [JACKSON-99] Should throw EOFException, closed thing
* semantically
*/
throw new EOFException("No content to map to Object due to end of input");
}
}
return t;
}
/*
////////////////////////////////////////////////////
// Internal methods, other
////////////////////////////////////////////////////
*/
/**
* Method called to locate deserializer for the passed root-level value.
*/
protected JsonDeserializer