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
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
66
67
68
69
70
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
97
98
99
100
101
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
118
119
120
121
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 }