All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.codehaus.jackson.map.ObjectMapper Maven / Gradle / Ivy

Go to download

Data Mapper package is a high-performance data binding package built on Jackson JSON processor

There is a newer version: 1.9.13
Show newest version
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.schema.JsonSchema;
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.NullNode;
import org.codehaus.jackson.node.ObjectNode;
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.fromClass(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 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); } public ObjectMapper(JsonFactory jf) { this(jf, null, null); } 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. */ _jsonFactory = (jf == null) ? new MappingJsonFactory() : 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; } /** * Method for setting specific {@link DeserializerProvider} to use * for handling caching of {@link JsonDeserializer} instances. */ public ObjectMapper setDeserializerProvider(DeserializerProvider p) { _deserializerProvider = p; return this; } /** * 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 Json factory that this * mapper uses if it needs to construct Json parsers and/or generators. * * @return Json factory 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.setParserFeature(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.setGeneratorFeature(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.fromClass(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.fromClass(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.fromTypeReference(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.fromTypeReference(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 { /* 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, copyDeserializationConfig()); 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 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; } /* //////////////////////////////////////////////////// // 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(); } /* //////////////////////////////////////////////////// // 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.fromClass(valueType)); } @SuppressWarnings("unchecked") public T readValue(File src, TypeReference valueTypeRef) throws IOException, JsonParseException, JsonMappingException { return (T) _readMapAndClose(_jsonFactory.createJsonParser(src), TypeFactory.fromTypeReference(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.fromClass(valueType)); } @SuppressWarnings("unchecked") public T readValue(URL src, TypeReference valueTypeRef) throws IOException, JsonParseException, JsonMappingException { return (T) _readMapAndClose(_jsonFactory.createJsonParser(src), TypeFactory.fromTypeReference(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.fromClass(valueType)); } @SuppressWarnings("unchecked") public T readValue(String content, TypeReference valueTypeRef) throws IOException, JsonParseException, JsonMappingException { return (T) _readMapAndClose(_jsonFactory.createJsonParser(content), TypeFactory.fromTypeReference(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.fromClass(valueType)); } @SuppressWarnings("unchecked") public T readValue(Reader src, TypeReference valueTypeRef) throws IOException, JsonParseException, JsonMappingException { return (T) _readMapAndClose(_jsonFactory.createJsonParser(src), TypeFactory.fromTypeReference(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.fromClass(valueType)); } @SuppressWarnings("unchecked") public T readValue(InputStream src, TypeReference valueTypeRef) throws IOException, JsonParseException, JsonMappingException { return (T) _readMapAndClose(_jsonFactory.createJsonParser(src), TypeFactory.fromTypeReference(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.fromClass(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.fromTypeReference(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); } /** * Generate the Json-schema} * for the specified class. * * @param t The class. * @return The json-schema. */ public JsonSchema generateJsonSchema(Class t) throws JsonMappingException { return generateJsonSchema(t, copySerializationConfig()); } 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) { } } } } /** * 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 _findRootDeserializer(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 = _deserializerProvider.findValueDeserializer(_deserializationConfig, valueType, null, null); if (deser == null) { // can this happen? throw new JsonMappingException("Can not find a deserializer for type "+valueType); } _rootDeserializers.put(valueType, deser); return deser; } protected DeserializationContext _createDeserializationContext(JsonParser jp, DeserializationConfig cfg) { return new StdDeserializationContext(cfg, jp); } }