|
@@ -0,0 +1,306 @@
|
|
|
+package cn.com.qmth.ac.util;
|
|
|
+
|
|
|
+import com.fasterxml.jackson.annotation.JsonInclude.Include;
|
|
|
+import com.fasterxml.jackson.core.JsonParser;
|
|
|
+import com.fasterxml.jackson.core.JsonProcessingException;
|
|
|
+import com.fasterxml.jackson.core.type.TypeReference;
|
|
|
+import com.fasterxml.jackson.databind.*;
|
|
|
+import com.fasterxml.jackson.databind.deser.std.StdScalarDeserializer;
|
|
|
+import com.fasterxml.jackson.databind.module.SimpleModule;
|
|
|
+import com.fasterxml.jackson.databind.util.JSONPObject;
|
|
|
+import org.apache.commons.lang3.StringUtils;
|
|
|
+import org.slf4j.Logger;
|
|
|
+import org.slf4j.LoggerFactory;
|
|
|
+
|
|
|
+import java.io.IOException;
|
|
|
+import java.text.SimpleDateFormat;
|
|
|
+import java.util.*;
|
|
|
+
|
|
|
+/**
|
|
|
+ * 简单封装Jackson,实现JSON 与 Java Object互相转换的Mapper 封装不同的输出风格, 使用不同的builder函数创建实例
|
|
|
+ */
|
|
|
+@SuppressWarnings("unchecked")
|
|
|
+public class JsonMapper {
|
|
|
+
|
|
|
+ private static final Logger LOG = LoggerFactory.getLogger(JsonMapper.class);
|
|
|
+
|
|
|
+ private ObjectMapper mapper;
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 默认构造JsonMapper
|
|
|
+ */
|
|
|
+ public JsonMapper() {
|
|
|
+ this(null);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建只输出初始值被改变的属性到Json字符串的Mapper, 最节约的存储方式
|
|
|
+ */
|
|
|
+ public static JsonMapper nonDefaultMapper() {
|
|
|
+ return new JsonMapper(Include.NON_DEFAULT);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建只输出非Null且非Empty的属性到Json字符串的Mapper
|
|
|
+ */
|
|
|
+ public static JsonMapper nonEmptyMapper() {
|
|
|
+ return new JsonMapper(Include.NON_EMPTY);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 创建只输出非Null的属性到Json字符串的Mapper
|
|
|
+ */
|
|
|
+ public static JsonMapper nonNullMapper() {
|
|
|
+ return new JsonMapper(Include.NON_NULL);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构造JsonMapper
|
|
|
+ */
|
|
|
+ public JsonMapper(Include include) {
|
|
|
+ mapper = new ObjectMapper();
|
|
|
+
|
|
|
+ SimpleModule module = new SimpleModule();
|
|
|
+ module.addDeserializer(String.class, new StdScalarDeserializer<String>(String.class) {
|
|
|
+
|
|
|
+ @Override
|
|
|
+ public String deserialize(JsonParser jsonParser, DeserializationContext ctx)
|
|
|
+ throws IOException, JsonProcessingException {
|
|
|
+ // 去掉头尾空格
|
|
|
+ return jsonParser.getValueAsString() != null ? jsonParser.getValueAsString().trim() : null;
|
|
|
+ }
|
|
|
+ });
|
|
|
+ mapper.registerModule(module);
|
|
|
+
|
|
|
+ // 设置输出时包含属性的风格
|
|
|
+ if (include != null) {
|
|
|
+ mapper.setSerializationInclusion(include);
|
|
|
+ }
|
|
|
+
|
|
|
+ // 设置输入时忽略在JSON字符串中存在但Java对象实际没有的属性
|
|
|
+ mapper.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES);
|
|
|
+
|
|
|
+ // 忽略无法转换的对象
|
|
|
+ mapper.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS);
|
|
|
+
|
|
|
+ // 设置默认日期格式
|
|
|
+ mapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Object可以是POJO,也可以是Collection或数组 如果对象为Null, 返回"null" 如果集合为空集合, 返回"[]"
|
|
|
+ */
|
|
|
+ public String toJson(Object object) {
|
|
|
+ if (object == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ return mapper.writeValueAsString(object);
|
|
|
+ } catch (IOException e) {
|
|
|
+ LOG.error("toJson error!" + e.getMessage(), e);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Object 转换为 Json(美化版) 若对象为 null 或 转换异常时,返回null 若集合为空集合,返回[]
|
|
|
+ */
|
|
|
+ public String toPrettyJson(Object object) {
|
|
|
+ if (object == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ return mapper.writerWithDefaultPrettyPrinter().writeValueAsString(object);
|
|
|
+ } catch (IOException e) {
|
|
|
+ LOG.error("toPrettyJson error! " + e.getMessage(), e);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 反序列化POJO或简单Collection如List<String> 如果JSON字符串为Null或"null"字符串, 返回Null
|
|
|
+ * 如果JSON字符串为"[]", 返回空集合 如需反序列化复杂Collection如List<MyBean>,
|
|
|
+ * 请使用parseJson(String, JavaType)
|
|
|
+ */
|
|
|
+ public <T> T parseJson(String jsonStr, Class<T> clazz) {
|
|
|
+ if (StringUtils.isEmpty(jsonStr)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ return mapper.readValue(jsonStr, clazz);
|
|
|
+ } catch (IOException e) {
|
|
|
+ LOG.error("parseJson error!" + e.getMessage(), e);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 反序列化复杂Collection如List<Bean>,
|
|
|
+ * 先使用createCollectionType()或constructMapType()构造类型, 然后调用本函数
|
|
|
+ */
|
|
|
+ public <T> T parseJson(String jsonStr, JavaType javaType) {
|
|
|
+ if (StringUtils.isEmpty(jsonStr)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ return (T) mapper.readValue(jsonStr, javaType);
|
|
|
+ } catch (IOException e) {
|
|
|
+ LOG.error("parseJson error!" + e.getMessage(), e);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 反序列化复杂的对象,如Page<Bean>
|
|
|
+ */
|
|
|
+ public <T> T parseJson(String jsonStr, TypeReference javaType) {
|
|
|
+ if (StringUtils.isEmpty(jsonStr)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ return (T) mapper.readValue(jsonStr, javaType);
|
|
|
+ } catch (IOException e) {
|
|
|
+ LOG.error("parseJson error!" + e.getMessage(), e);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Json 转换为 T[] 若Json字符串为 null 或 empty 或 转换异常时,返回null
|
|
|
+ */
|
|
|
+ public <T> T[] toArray(String jsonStr, Class<T> clazz) {
|
|
|
+ JavaType javaType = this.constructArrayType(clazz);
|
|
|
+ return this.parseJson(jsonStr, javaType);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Json to List
|
|
|
+ */
|
|
|
+ public <T> List<T> toList(String jsonStr, Class<T> bean) {
|
|
|
+ if (StringUtils.isEmpty(jsonStr)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ JavaType javaType = constructCollectionType(List.class, bean);
|
|
|
+ return mapper.readValue(jsonStr, javaType);
|
|
|
+ } catch (IOException e) {
|
|
|
+ LOG.error("parseJson error!" + e.getMessage(), e);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Json 转换为 Set<T> 若Json字符串为 null 或 empty 或 转换异常时,返回null
|
|
|
+ */
|
|
|
+ public <T> Set<T> toSet(String jsonStr, Class<T> clazz) {
|
|
|
+ JavaType javaType = this.constructCollectionType(Set.class, clazz);
|
|
|
+ return this.parseJson(jsonStr, javaType);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * Json to HashMap
|
|
|
+ */
|
|
|
+ public <T> Map<String, T> toMap(String jsonStr, Class<T> bean) {
|
|
|
+ if (StringUtils.isEmpty(jsonStr)) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ JavaType javaType = constructMapType(HashMap.class, String.class, bean);
|
|
|
+ return mapper.readValue(jsonStr, javaType);
|
|
|
+ } catch (IOException e) {
|
|
|
+ LOG.error("parseJson error!" + e.getMessage(), e);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构造Array类型
|
|
|
+ */
|
|
|
+ public JavaType constructArrayType(Class<?> elementClass) {
|
|
|
+ return mapper.getTypeFactory().constructArrayType(elementClass);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构造Collection类型
|
|
|
+ */
|
|
|
+ public JavaType constructCollectionType(Class<? extends Collection> collectionClass, Class<?> elementClass) {
|
|
|
+ return mapper.getTypeFactory().constructCollectionType(collectionClass, elementClass);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 构造Map类型
|
|
|
+ */
|
|
|
+ public JavaType constructMapType(Class<? extends Map> mapClass, Class<?> keyClass, Class<?> valueClass) {
|
|
|
+ return mapper.getTypeFactory().constructMapType(mapClass, keyClass, valueClass);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 当JSON里只含有Bean的部分属性時,更新一個已存在Bean,只覆盖該部分的属性
|
|
|
+ */
|
|
|
+ public void update(String jsonStr, Object object) {
|
|
|
+ if (jsonStr == null) {
|
|
|
+ return;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ mapper.readerForUpdating(object).readValue(jsonStr);
|
|
|
+ } catch (JsonProcessingException e) {
|
|
|
+ LOG.error("updateJson error!" + e.getMessage(), e);
|
|
|
+ } catch (IOException e) {
|
|
|
+ LOG.error("updateJson error!" + e.getMessage(), e);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 輸出JSONP格式数据
|
|
|
+ */
|
|
|
+ public String toJsonP(String functionName, Object object) {
|
|
|
+ if (object == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ return toJson(new JSONPObject(functionName, object));
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 設定是否使用Enum的toString函数來读写Enum 为False時使用Enum的name()函数來读写Enum, 默认为False
|
|
|
+ * 注意本函数一定要在Mapper創建後, 所有的读写動作之前調用
|
|
|
+ */
|
|
|
+ public void enableEnumUseToString() {
|
|
|
+ mapper.enable(SerializationFeature.WRITE_ENUMS_USING_TO_STRING);
|
|
|
+ mapper.enable(DeserializationFeature.READ_ENUMS_USING_TO_STRING);
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 取出Mapper做进一步的设置或使用其他序列化API
|
|
|
+ */
|
|
|
+ public ObjectMapper getMapper() {
|
|
|
+ return mapper;
|
|
|
+ }
|
|
|
+
|
|
|
+ /***
|
|
|
+ * 把Json字符串转换成Node对象
|
|
|
+ */
|
|
|
+ public JsonNode getNode(String jsonStr) {
|
|
|
+ if (jsonStr == null) {
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+
|
|
|
+ try {
|
|
|
+ // mapper.configure(JsonParser.Feature.ALLOW_UNQUOTED_CONTROL_CHARS,
|
|
|
+ // true);
|
|
|
+ return mapper.readTree(jsonStr);
|
|
|
+ } catch (IOException e) {
|
|
|
+ LOG.error(e.getMessage(), e);
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+}
|