package at.gv.egiz.eaaf.core.impl.utils; import java.io.IOException; import com.fasterxml.jackson.annotation.JsonAutoDetect.Visibility; import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JavaType; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.SerializationFeature; import com.fasterxml.jackson.databind.type.TypeFactory; import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import at.gv.egiz.eaaf.core.exceptions.EaafJsonMapperException; import lombok.Getter; import lombok.extern.slf4j.Slf4j; /** * Holder for Jackson JSON Mapper that sets some security features. * * @author tlenz * */ @Slf4j public final class DefaultJsonMapper { @Getter private static final ObjectMapper jsonMapper = new ObjectMapper(); static { // initialize JSON Mapper jsonMapper.configure(DeserializationFeature.FAIL_ON_READING_DUP_TREE_KEY, true); jsonMapper.configure(DeserializationFeature.FAIL_ON_TRAILING_TOKENS, true); jsonMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, true); jsonMapper.setVisibility(PropertyAccessor.ALL, Visibility.NONE); jsonMapper.setVisibility(PropertyAccessor.GETTER, Visibility.PUBLIC_ONLY); jsonMapper.setVisibility(PropertyAccessor.IS_GETTER, Visibility.PUBLIC_ONLY); jsonMapper.registerModule(new JavaTimeModule()); jsonMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false); } /** * private constructor for class with only static methods. */ private DefaultJsonMapper() { } /** * Serialize an object to a JSON string. * * @param value the object to serialize * @return a JSON string * @throws JsonProcessingException thrown when an error occurs during * serialization */ public static String serialize(final Object value) throws EaafJsonMapperException { try { return jsonMapper.writeValueAsString(value); } catch (final JsonProcessingException e) { log.warn("JSON mapping FAILED with error: {}", e.getMessage()); throw new EaafJsonMapperException(e.getMessage(), e); } } /** * Deserialize a JSON string. * * @param value the JSON to deserialize as {@link String} * @param clazz optional parameter that determines the type of the returned * object. If not set, an {@link Object} is returned. * @param Response class type * @return the deserialized JSON string as an object of type {@code clazz} or * {@link Object} * @throws JsonMappingException if the input JSON structure does not match * structure expected for result type */ public static Object deserialize(final String value, final Class clazz) throws EaafJsonMapperException { try { if (clazz != null) { if (clazz.isAssignableFrom(TypeReference.class)) { return jsonMapper.readValue(value, clazz); } else { final JavaType javaType = TypeFactory.defaultInstance().constructType(clazz); return jsonMapper.readValue(value, javaType); } } else { return jsonMapper.readValue(value, Object.class); } } catch (final IOException e) { log.warn("JSON mapping FAILED with error: {}", e.getMessage()); throw new EaafJsonMapperException(e.getMessage(), e); } } }