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

com.palantir.conjure.java.serialization.ObjectMappers Maven / Gradle / Ivy

There is a newer version: 8.16.0
Show newest version
/*
 * (c) Copyright 2017 Palantir Technologies Inc. All rights reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.palantir.conjure.java.serialization;

import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.StreamReadConstraints;
import com.fasterxml.jackson.core.TSFBuilder;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.MapperFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
import com.fasterxml.jackson.databind.cfg.MapperBuilder;
import com.fasterxml.jackson.databind.json.JsonMapper;
import com.fasterxml.jackson.dataformat.cbor.CBORFactory;
import com.fasterxml.jackson.dataformat.cbor.databind.CBORMapper;
import com.fasterxml.jackson.dataformat.smile.SmileFactory;
import com.fasterxml.jackson.dataformat.smile.SmileGenerator;
import com.fasterxml.jackson.dataformat.smile.databind.SmileMapper;
import com.fasterxml.jackson.datatype.guava.GuavaModule;
import com.fasterxml.jackson.datatype.jdk8.Jdk8Module;
import com.fasterxml.jackson.datatype.joda.JodaModule;
import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule;
import com.palantir.conjure.java.jackson.optimizations.ObjectMapperOptimizations;

public final class ObjectMappers {

    private ObjectMappers() {}

    /**
     * Returns a default ObjectMapper with settings adjusted for use in clients.
     *
     * 

Settings: * *

    *
  • Ignore unknown properties found during deserialization. *
*/ public static JsonMapper newClientJsonMapper() { return withDefaultModules(JsonMapper.builder(jsonFactory())) .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) .build(); } /** * Returns a default ObjectMapper which uses the cbor factory with settings adjusted for use in clients. * *

Settings: * *

    *
  • Ignore unknown properties found during deserialization. *
*/ public static CBORMapper newClientCborMapper() { return withDefaultModules(CBORMapper.builder(cborFactory())) .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) .build(); } /** * Returns a default ObjectMapper which uses the cbor factory with settings adjusted for use in clients. * *

Settings: * *

    *
  • Disable 7-bit binary encoding. *
  • Ignore unknown properties found during deserialization. *
*/ public static SmileMapper newClientSmileMapper() { return withDefaultModules(SmileMapper.builder(smileFactory())) .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) .build(); } /** * Returns a default ObjectMapper with settings adjusted for use in servers. * *

Settings: * *

    *
  • Throw on unknown properties found during deserialization. *
*/ public static JsonMapper newServerJsonMapper() { return withDefaultModules(JsonMapper.builder(jsonFactory())) .enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) .build(); } /** * Returns a default ObjectMapper which uses the cbor factory with settings adjusted for use in servers. * *

Settings: * *

    *
  • Throw on unknown properties found during deserialization. *
*/ public static CBORMapper newServerCborMapper() { return withDefaultModules(CBORMapper.builder(cborFactory())) .enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) .build(); } /** * Returns a default ObjectMapper which uses the smile factory with settings adjusted for use in servers. * *

Settings: * *

    *
  • Disable 7-bit binary encoding. *
  • Throw on unknown properties found during deserialization. *
*/ public static SmileMapper newServerSmileMapper() { return withDefaultModules(SmileMapper.builder(smileFactory())) .enable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) .build(); } public static ObjectMapper newClientObjectMapper() { return newClientJsonMapper(); } public static ObjectMapper newCborClientObjectMapper() { return newClientCborMapper(); } public static ObjectMapper newSmileClientObjectMapper() { return newClientSmileMapper(); } public static ObjectMapper newServerObjectMapper() { return newServerJsonMapper(); } public static ObjectMapper newCborServerObjectMapper() { return newServerCborMapper(); } public static ObjectMapper newSmileServerObjectMapper() { return newServerSmileMapper(); } /** * Configures provided MapperBuilder with default modules and settings. * *

Modules: Guava, JDK7, JDK8, Afterburner, JavaTime, Joda * *

Settings: * *

    *
  • Dates written as ISO-8601 strings. *
  • Dates remain in received timezone. *
  • Exceptions will not be wrapped with Jackson exceptions. *
  • Deserializing a null for a primitive field will throw an exception. *
*/ public static > B withDefaultModules(B builder) { return builder.typeFactory(NonCachingTypeFactory.from(builder.build().getTypeFactory())) .addModule(new GuavaModule()) .addModule(new ShimJdk7Module()) .addModule(new Jdk8Module().configureAbsentsAsNulls(true)) .addModules(ObjectMapperOptimizations.createModules()) .addModule(new JavaTimeModule()) .addModule(new LenientLongModule()) // we strongly recommend using built-in java.time classes instead of joda ones. Joda deserialization // was implicit up until jackson 2.12 .addModule(new JodaModule()) .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) .disable(SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS) .disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE) .disable(DeserializationFeature.WRAP_EXCEPTIONS) .disable(SerializationFeature.FAIL_ON_EMPTY_BEANS) .enable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES) .disable(MapperFeature.ALLOW_COERCION_OF_SCALARS) .disable(DeserializationFeature.ACCEPT_FLOAT_AS_INT); } /** * Configures provided ObjectMapper with default modules and settings. * *

Modules: Guava, JDK7, JDK8, Afterburner, JavaTime, Joda * *

Settings: * *

    *
  • Dates written as ISO-8601 strings. *
  • Dates remain in received timezone. *
  • Exceptions will not be wrapped with Jackson exceptions. *
  • Deserializing a null for a primitive field will throw an exception. *
*/ public static ObjectMapper withDefaultModules(ObjectMapper mapper) { return mapper.setTypeFactory(NonCachingTypeFactory.from(mapper.getTypeFactory())) .registerModule(new GuavaModule()) .registerModule(new ShimJdk7Module()) .registerModule(new Jdk8Module().configureAbsentsAsNulls(true)) .registerModules(ObjectMapperOptimizations.createModules()) .registerModule(new JavaTimeModule()) .registerModule(new LenientLongModule()) // we strongly recommend using built-in java.time classes instead of joda ones. Joda deserialization // was implicit up until jackson 2.12 .registerModule(new JodaModule()) .disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS) .disable(SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS) .disable(DeserializationFeature.ADJUST_DATES_TO_CONTEXT_TIME_ZONE) .disable(DeserializationFeature.WRAP_EXCEPTIONS) .disable(SerializationFeature.FAIL_ON_EMPTY_BEANS) .enable(DeserializationFeature.FAIL_ON_NULL_FOR_PRIMITIVES) .disable(MapperFeature.ALLOW_COERCION_OF_SCALARS) .disable(DeserializationFeature.ACCEPT_FLOAT_AS_INT); } /** Creates a new {@link JsonFactory} configured with Conjure defaults. */ public static JsonFactory jsonFactory() { return withDefaults(InstrumentedJsonFactory.builder()).build(); } /** Creates a new {@link SmileFactory} configured with Conjure defaults. */ public static SmileFactory smileFactory() { return withDefaults(InstrumentedSmileFactory.builder().disable(SmileGenerator.Feature.ENCODE_BINARY_AS_7BIT)) .build(); } /** Creates a new {@link CBORFactory} configured with Conjure defaults. */ public static CBORFactory cborFactory() { return withDefaults(CBORFactory.builder()).build(); } /** Configures provided JsonFactory with Conjure default settings. */ private static > B withDefaults(B builder) { return builder // Interning introduces excessive contention https://github.com/FasterXML/jackson-core/issues/946 .disable(JsonFactory.Feature.INTERN_FIELD_NAMES) // Canonicalization can be helpful to avoid string re-allocation, however we expect unbounded // key space due to use of maps keyed by random identifiers, which cause heavy heap churn. // See this discussion: https://github.com/FasterXML/jackson-benchmarks/pull/6 .disable(JsonFactory.Feature.CANONICALIZE_FIELD_NAMES) .streamReadConstraints(StreamReadConstraints.builder() // 50mb up from the default 20mb as a more permissive value to begin with, which we can ratchet // down over time. This allows us to decouple the initial risk of adopting string length limits // from the risk introduced by taking a dependency upgrade. .maxStringLength(50_000_000) .build()); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy