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

br.pro.hashi.sdx.rest.jackson.JacksonInjector Maven / Gradle / Ivy

package br.pro.hashi.sdx.rest.jackson;

import java.lang.invoke.MethodHandles;
import java.lang.invoke.MethodHandles.Lookup;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.core.json.JsonReadFeature;
import com.fasterxml.jackson.core.json.JsonWriteFeature;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;

import br.pro.hashi.sdx.rest.Builder;
import br.pro.hashi.sdx.rest.client.RestClientBuilder;
import br.pro.hashi.sdx.rest.jackson.transform.ConverterFactory;
import br.pro.hashi.sdx.rest.jackson.transform.ConverterMapper;
import br.pro.hashi.sdx.rest.jackson.transform.ConverterModule;
import br.pro.hashi.sdx.rest.jackson.transform.JacksonDeserializer;
import br.pro.hashi.sdx.rest.jackson.transform.JacksonSerializer;
import br.pro.hashi.sdx.rest.server.RestServerBuilder;
import br.pro.hashi.sdx.rest.transform.extension.Injector;

/**
 * Injects a Jackson serializer and a Jackson deserializer in a
 * {@link RestClientBuilder} or a {@link RestServerBuilder}.
 */
public class JacksonInjector extends Injector {
	private static final JacksonInjector INSTANCE = new JacksonInjector();
	private static final Lookup LOOKUP = MethodHandles.lookup();

	/**
	 * Represents the JSON content type.
	 */
	public static final String JSON_TYPE = "application/json";

	/**
	 * Obtains an injector instance.
	 *
	 * @return the instance
	 */
	public static JacksonInjector getInstance() {
		return INSTANCE;
	}

	private final Logger logger;

	private JacksonInjector() {
		this.logger = LoggerFactory.getLogger(JacksonInjector.class);
	}

	/**
	 * 

* Injects a default serializer and a default deserializer in the specified * client or server builder. *

*

* This method uses an {@link ObjectMapper} with a default configuration. * Namely, with the options below. *

* *
	 * {@code   .enable(SerializationFeature.INDENT_OUTPUT)
	 *   .enable(JsonReadFeature.ALLOW_NON_NUMERIC_NUMBERS.mappedFeature())
	 *   .disable(SerializationFeature.FAIL_ON_EMPTY_BEANS)
	 *   .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
	 *   .disable(JsonWriteFeature.WRITE_NAN_AS_STRINGS.mappedFeature())
	 *   .setVisibility(PropertyAccessor.ALL, Visibility.NONE)
	 *   .setVisibility(PropertyAccessor.FIELD, Visibility.ANY)}
	 * 
* * @param builder the client or server builder * @throws NullPointerException if the client or server builder is null */ public final void inject(Builder builder) { inject(builder, defaultObjectMapper()); } /** *

* Injects a custom serializer and a custom deserializer in the specified client * or server builder. *

*

* This method uses the specified {@link ObjectMapper}. *

* * @param builder the client or server builder * @param objectMapper the object mapper * @throws NullPointerException if the client or server builder is null or the * object mapper is null */ public final void inject(Builder builder, ObjectMapper objectMapper) { inject(builder, new ConverterMapper(new ConverterFactory(objectMapper), objectMapper)); } /** *

* Injects an extended default serializer and an extended default deserializer * in the specified client or server builder. *

*

* This method uses an {@link ObjectMapper} with a default configuration (see * {@code inject(Builder)}) and extends its type support with instances of * all concrete implementations of {@link JacksonConverter} in the specified * package (including subpackages). *

* * @param builder the client or server builder * @param packageName the package name * @throws NullPointerException if the client or server builder is null or the * package name is null */ public final void inject(Builder builder, String packageName) { inject(builder, defaultObjectMapper(), packageName); } /** *

* Injects an extended custom serializer and an extended custom deserializer in * the specified client or server builder. *

*

* This method uses the specified {@link ObjectMapper} and extends its type * support (see {@code inject(Builder, String)}). *

* * @param builder the client or server builder * @param objectMapper the object mapper * @param packageName the package name * @throws NullPointerException if the client or server builder is null, the * object mapper is null, or the package name is * null */ public final void inject(Builder builder, ObjectMapper objectMapper, String packageName) { ConverterFactory converterFactory = new ConverterFactory(objectMapper); ConverterModule module = new ConverterModule(converterFactory); for (JacksonConverter converter : getSubConverters(packageName, JacksonConverter.class, LOOKUP)) { module.registerConverter(converter); logger.info("Registered %s".formatted(converter.getClass().getName())); } objectMapper.registerModule(module); inject(builder, new ConverterMapper(converterFactory, objectMapper)); } private void inject(Builder builder, ConverterMapper converterMapper) { if (builder == null) { throw new NullPointerException("Builder cannot be null"); } builder.withSerializer(JSON_TYPE, new JacksonSerializer(converterMapper)); builder.withDeserializer(JSON_TYPE, new JacksonDeserializer(converterMapper)); } private ObjectMapper defaultObjectMapper() { return new ObjectMapper() .enable(SerializationFeature.INDENT_OUTPUT) .enable(JsonReadFeature.ALLOW_NON_NUMERIC_NUMBERS.mappedFeature()) .disable(SerializationFeature.FAIL_ON_EMPTY_BEANS) .disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES) .disable(JsonWriteFeature.WRITE_NAN_AS_STRINGS.mappedFeature()) .setVisibility(PropertyAccessor.ALL, Visibility.NONE) .setVisibility(PropertyAccessor.FIELD, Visibility.ANY); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy