View Javadoc
1   package cn.home1.oss.lib.common;
2   
3   import static java.util.stream.Collectors.toSet;
4   
5   import com.fasterxml.jackson.core.JsonProcessingException;
6   import com.fasterxml.jackson.core.type.TypeReference;
7   import com.fasterxml.jackson.databind.ObjectMapper;
8   
9   import lombok.extern.slf4j.Slf4j;
10  
11  import org.springframework.core.env.PropertyResolver;
12  import org.springframework.util.ClassUtils;
13  
14  import java.io.IOException;
15  import java.util.Arrays;
16  import java.util.Set;
17  import java.util.function.Function;
18  
19  /**
20   * Created by zhanghaolun on 16/6/9.
21   */
22  @Slf4j
23  public final class Jackson2Utils {
24  
25    private Jackson2Utils() {
26    }
27  
28    private static final Boolean JACKSON2_PRESENT = ClassUtils.isPresent( //
29      "com.fasterxml.jackson.databind.ObjectMapper", //
30      Thread.currentThread().getContextClassLoader() //
31    ) && ClassUtils.isPresent( //
32      "com.fasterxml.jackson.core.JsonGenerator", //
33      Thread.currentThread().getContextClassLoader() //
34    );
35  
36    public static class RuntimeJsonProcessingException extends RuntimeException {
37  
38      private static final long serialVersionUID = 1L;
39  
40      public RuntimeJsonProcessingException(final String message, final Throwable cause) {
41        super(message, cause);
42      }
43    }
44  
45    public static Boolean getJackson2Present() {
46      return Jackson2Utils.JACKSON2_PRESENT;
47    }
48  
49    @SuppressWarnings("rawtypes")
50    static Set<Jackson2Configurator> scanJackson2Configurators() {
51      final String basePackage = Jackson2Utils.class.getName().split("\\.")[0];
52      final Set<Class<Jackson2Configurator>> configurators = FileAndClasspathUtils.scan(basePackage,
53        new FileAndClasspathUtils.AssignableFilter(Jackson2Configurator.class, false, true));
54  
55      if (configurators.isEmpty()) {
56        log.warn("no {} found.", Jackson2Configurator.class.getSimpleName());
57      }
58  
59      return configurators.stream() //
60        .flatMap(configurator -> Arrays.stream(configurator.getEnumConstants())) //
61        .collect(toSet());
62    }
63  
64    /**
65     * Setup a Mapper.
66     *
67     * @param propertyResolver propertyResolver
68     * @param objectMapper     to setup
69     * @param <T>              ObjectMapper or XmlMapper
70     * @return same instance of objectMapper param
71     */
72    @SuppressWarnings("rawtypes")
73    public static <T extends ObjectMapper> T setupObjectMapper( //
74      final PropertyResolver propertyResolver, final T objectMapper) {
75      for (final Jackson2Configurator instance : scanJackson2Configurators()) {
76        log.info("config objectMapper: '{}' using: '{}'.", objectMapper, instance);
77        instance.config(propertyResolver, objectMapper);
78      }
79      return objectMapper;
80    }
81  
82    public static <T> Function<String, T> fromJson( //
83      final ObjectMapper objectMapper, //
84      final TypeReference<T> typeReference //
85    ) {
86      return string -> {
87        try {
88          return objectMapper.readValue(string, typeReference);
89        } catch (final IOException wrapped) {
90          throw new RuntimeJsonProcessingException("error read from JSON.", wrapped);
91        }
92      };
93    }
94  
95    /**
96     * parse JSON.
97     *
98     * @param objectMapper objectMapper
99     * @param type         type
100    * @param <T>          type
101    * @return object
102    */
103   public static <T> Function<String, T> fromJson( //
104     final ObjectMapper objectMapper, //
105     final Class<T> type //
106   ) {
107     return string -> {
108       try {
109         return objectMapper.readValue(string, type);
110       } catch (final IOException wrapped) {
111         throw new RuntimeJsonProcessingException("error read from JSON.", wrapped);
112       }
113     };
114   }
115 
116   /**
117    * to JSON.
118    *
119    * @param objectMapper objectMapper
120    * @param <T>          type
121    * @return JSON
122    */
123   public static <T> Function<T, String> toJson(final ObjectMapper objectMapper) {
124     return object -> {
125       try {
126         if (object != null) {
127           return objectMapper.writeValueAsString(object);
128         } else {
129           return "";
130         }
131       } catch (final JsonProcessingException wrapped) {
132         throw new RuntimeJsonProcessingException("error serialize to JSON.", wrapped);
133       }
134     };
135   }
136 
137   public static <T> String toJson(final ObjectMapper objectMapper, final T item) {
138     return toJson(objectMapper).apply(item);
139   }
140 }