|
@@ -1,9 +1,11 @@
|
|
|
package com.emato.ccnet.util;
|
|
|
|
|
|
-import com.emato.ccnet.config.jackson.JacksonStringUnicodeSerializer;
|
|
|
import com.fasterxml.jackson.annotation.JsonFilter;
|
|
|
import com.fasterxml.jackson.annotation.JsonInclude;
|
|
|
-import com.fasterxml.jackson.core.*;
|
|
|
+import com.fasterxml.jackson.core.JsonGenerationException;
|
|
|
+import com.fasterxml.jackson.core.JsonGenerator;
|
|
|
+import com.fasterxml.jackson.core.JsonParseException;
|
|
|
+import com.fasterxml.jackson.core.JsonParser;
|
|
|
import com.fasterxml.jackson.core.type.TypeReference;
|
|
|
import com.fasterxml.jackson.databind.DeserializationFeature;
|
|
|
import com.fasterxml.jackson.databind.JsonMappingException;
|
|
@@ -29,6 +31,8 @@ import java.time.LocalDate;
|
|
|
import java.time.LocalDateTime;
|
|
|
import java.time.LocalTime;
|
|
|
import java.time.format.DateTimeFormatter;
|
|
|
+import java.util.Date;
|
|
|
+import java.util.Locale;
|
|
|
|
|
|
/**
|
|
|
* @author Scott Chen
|
|
@@ -44,8 +48,6 @@ public class JacksonUtil {
|
|
|
private static final String DYNC_INCLUDE = "DYNC_INCLUDE";//包含的标识
|
|
|
private static final String DYNC_EXCLUDE = "DYNC_EXCLUDE";//过滤的标识
|
|
|
|
|
|
- private static ObjectMapper mapper = new ObjectMapper();
|
|
|
-
|
|
|
@JsonFilter(DYNC_EXCLUDE)
|
|
|
interface DynamicExclude{
|
|
|
|
|
@@ -56,12 +58,25 @@ public class JacksonUtil {
|
|
|
|
|
|
}
|
|
|
/**
|
|
|
+ * 禁止调用无参构造
|
|
|
+ *
|
|
|
+ * @throws IllegalAccessException
|
|
|
+ */
|
|
|
+ private JacksonUtil() throws IllegalAccessException {
|
|
|
+ throw new IllegalAccessException("Can't create an instance!");
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
* 懒惰单例模式得到ObjectMapper实例
|
|
|
* 此对象为Jackson的核心
|
|
|
*/
|
|
|
- private static ObjectMapper objectMapper() {
|
|
|
+ private static final ObjectMapper objectMapper() {
|
|
|
if (objectMapper== null){
|
|
|
objectMapper= new ObjectMapper();
|
|
|
+
|
|
|
+ // 格式化国家环境指定
|
|
|
+ objectMapper.setLocale(Locale.SIMPLIFIED_CHINESE);
|
|
|
+
|
|
|
//序列化时,如果没有为类型找到访问者,则会抛出异常以将其指定为非可序列化类型; 如果禁用,它们将被序列化为空对象
|
|
|
objectMapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
|
|
|
//反序列化时,遇到未知属性是否抛JsonMappingException异常.默认JsonMappingException
|
|
@@ -69,10 +84,15 @@ public class JacksonUtil {
|
|
|
//设置null值不参与序列化(字段不被显示)
|
|
|
objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);
|
|
|
|
|
|
- //序列化LocalDateTime时间
|
|
|
- objectMapper.registerModule(dateSerModule());
|
|
|
- //反序列化LocalDateTime时间
|
|
|
- objectMapper.registerModule(dateDeserModule());
|
|
|
+ //注册序列化LocalDateTime模块
|
|
|
+ objectMapper.registerModule(localDateTimeSerializer());
|
|
|
+ //注册反序列化LocalDateTime模块
|
|
|
+ objectMapper.registerModule(localDateTimeDeserializer());
|
|
|
+
|
|
|
+ //注册序列化Date模块
|
|
|
+ objectMapper.registerModule(dateTimeSerializer());
|
|
|
+ //注册反序列化Date模块
|
|
|
+ objectMapper.registerModule(dateTimeDeserializer());
|
|
|
|
|
|
//序列化Unicode编码非ASCII字符
|
|
|
//objectMapper.registerModule(unicodeSerModule());
|
|
@@ -82,40 +102,74 @@ public class JacksonUtil {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
+ * 序列化Date
|
|
|
+ * 自定义
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private static SimpleModule dateTimeSerializer(){
|
|
|
+ SimpleModule module = new SimpleModule();
|
|
|
+ module.addSerializer(Date.class, new DateTimeSerializer());
|
|
|
+ return module;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * 反列化Date
|
|
|
+ * 自定义
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ private static SimpleModule dateTimeDeserializer(){
|
|
|
+ SimpleModule module = new SimpleModule();
|
|
|
+ module.addDeserializer(Date.class, new DateTimeDeserializer());
|
|
|
+ return module;
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
* 序列化LocalDateTime时间
|
|
|
+ * 使用 <code>jackson-datatype-jsr310</code>
|
|
|
* @return
|
|
|
*/
|
|
|
- public static SimpleModule dateSerModule() {
|
|
|
- SimpleModule dateSerModule = new SimpleModule();
|
|
|
- dateSerModule.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
|
|
|
- dateSerModule.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
|
|
|
- dateSerModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
|
|
- return dateSerModule;
|
|
|
+ private static SimpleModule localDateTimeSerializer() {
|
|
|
+ SimpleModule module = new SimpleModule();
|
|
|
+ module.addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(DateConstant.DATE_MONTH_DAY, Locale.SIMPLIFIED_CHINESE)));
|
|
|
+ module.addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(DateConstant.TIME_SECOND, Locale.SIMPLIFIED_CHINESE)));
|
|
|
+ module.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(DateConstant.DATE_TIME_SECOND, Locale.SIMPLIFIED_CHINESE)));
|
|
|
+ return module;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 反序列化LocalDateTime时间
|
|
|
+ * 使用 <code>jackson-datatype-jsr310</code>
|
|
|
* @return
|
|
|
*/
|
|
|
- public static SimpleModule dateDeserModule() {
|
|
|
- SimpleModule dateDeserModule = new SimpleModule();
|
|
|
- dateDeserModule.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd")));
|
|
|
- dateDeserModule.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern("HH:mm:ss")));
|
|
|
- dateDeserModule.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));
|
|
|
- return dateDeserModule;
|
|
|
+ private static SimpleModule localDateTimeDeserializer() {
|
|
|
+ SimpleModule module = new SimpleModule();
|
|
|
+ module.addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(DateConstant.DATE_MONTH_DAY, Locale.SIMPLIFIED_CHINESE)));
|
|
|
+ module.addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(DateConstant.TIME_SECOND, Locale.SIMPLIFIED_CHINESE)));
|
|
|
+ module.addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(DateConstant.DATE_TIME_SECOND, Locale.SIMPLIFIED_CHINESE)));
|
|
|
+ return module;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
/**
|
|
|
* 序列化Unicode编码非ASCII字符
|
|
|
*/
|
|
|
- public static SimpleModule unicodeSerModule() {
|
|
|
+ private static SimpleModule unicodeSerModule() {
|
|
|
SimpleModule unicodeSerModule = new SimpleModule();
|
|
|
unicodeSerModule.addSerializer(String.class, new JacksonStringUnicodeSerializer());
|
|
|
return unicodeSerModule;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
+ * ObjectMapper 实例
|
|
|
+ * @return
|
|
|
+ */
|
|
|
+ public static ObjectMapper getObjectMapper() {
|
|
|
+ return objectMapper();
|
|
|
+ }
|
|
|
+
|
|
|
+ /**
|
|
|
* 创建Json处理器的静态方法
|
|
|
+ * 用于序列化
|
|
|
* @param content Json字符串
|
|
|
* @return
|
|
|
*/
|
|
@@ -129,6 +183,7 @@ public class JacksonUtil {
|
|
|
|
|
|
/**
|
|
|
* 创建Byte Json处理器的静态方法
|
|
|
+ * 用于序列化
|
|
|
* @param data byte array
|
|
|
* @return
|
|
|
*/
|
|
@@ -142,6 +197,7 @@ public class JacksonUtil {
|
|
|
|
|
|
/**
|
|
|
* 创建Reader Json处理器的静态方法
|
|
|
+ * 用于序列化
|
|
|
* @param r Reader
|
|
|
* @return
|
|
|
*/
|
|
@@ -155,6 +211,7 @@ public class JacksonUtil {
|
|
|
|
|
|
/**
|
|
|
* 创建InputStream Json处理器的静态方法
|
|
|
+ * 用于序列化
|
|
|
* @param in InputStream
|
|
|
* @return
|
|
|
*/
|
|
@@ -169,6 +226,7 @@ public class JacksonUtil {
|
|
|
|
|
|
/**
|
|
|
* 创建Json生成器的静态方法, 使用标准输出
|
|
|
+ * 用于反序列化
|
|
|
* @return
|
|
|
*/
|
|
|
private static JsonGenerator getGenerator(StringWriter sw){
|
|
@@ -179,6 +237,35 @@ public class JacksonUtil {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * Json对象序列化
|
|
|
+ */
|
|
|
+ public static String toJson(Object obj){
|
|
|
+ StringWriter sw= new StringWriter();
|
|
|
+ JsonGenerator jsonGen= getGenerator(sw);
|
|
|
+ if (jsonGen== null){
|
|
|
+ try {
|
|
|
+ sw.close();
|
|
|
+ } catch (IOException e) {
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
+ try {
|
|
|
+ //由于在getGenerator方法中指定了OutputStream为sw
|
|
|
+ //因此调用writeObject会将数据输出到sw
|
|
|
+ jsonGen.writeObject(obj);
|
|
|
+ //由于采用流式输出 在输出完毕后务必清空缓冲区并关闭输出流
|
|
|
+ jsonGen.flush();
|
|
|
+ jsonGen.close();
|
|
|
+ return sw.toString();
|
|
|
+ } catch (JsonGenerationException jge) {
|
|
|
+ logger.error("toJSON序列化失败, 异常类型【JsonGenerationException】,错误原因:{}", jge.getMessage());
|
|
|
+ } catch (IOException ioe) {
|
|
|
+ logger.error("toJSON序列化失败, 异常类型【IOException】, 错误原因:{}", ioe.getMessage());
|
|
|
+ ioe.printStackTrace();
|
|
|
+ }
|
|
|
+ return null;
|
|
|
+ }
|
|
|
|
|
|
|
|
|
/**
|
|
@@ -192,12 +279,12 @@ public class JacksonUtil {
|
|
|
try {
|
|
|
JsonParser jp= getByteParser(data);
|
|
|
return jp.readValueAs(clazz);
|
|
|
- } catch (JsonParseException jpe){
|
|
|
- logger.error(String.format("反序列化失败, 错误原因:%s", jpe.getMessage()));
|
|
|
- } catch (JsonMappingException jme){
|
|
|
- logger.error(String.format("反序列化失败, 错误原因:%s", jme.getMessage()));
|
|
|
- } catch (IOException ioe){
|
|
|
- logger.error(String.format("反序列化失败, 错误原因:%s", ioe.getMessage()));
|
|
|
+ } catch (JsonParseException e){
|
|
|
+ logger.error(String.format("fromByteJson反序列化失败, 异常类型【JsonParseException】, 错误原因:{}", e.getMessage()));
|
|
|
+ } catch (JsonMappingException e){
|
|
|
+ logger.error(String.format("fromByteJson反序列化失败, 异常类型【JsonMappingException】, 错误原因:{}", e.getMessage()));
|
|
|
+ } catch (IOException e){
|
|
|
+ logger.error(String.format("fromByteJson反序列化失败, 异常类型【IOException】, 错误原因:{}", e.getMessage()));
|
|
|
}
|
|
|
return null;
|
|
|
}
|
|
@@ -214,13 +301,13 @@ public class JacksonUtil {
|
|
|
JsonParser jp= getParser(json);
|
|
|
return (T) jp.readValueAs(clazz);
|
|
|
} catch (JsonParseException e) {
|
|
|
- logger.error(String.format("反序列化失败, 错误原因:%s", e.getMessage()));
|
|
|
+ logger.error(String.format("fromStringJson反序列化失败, 异常类型【JsonParseException】, 错误原因:{}", e.getMessage()));
|
|
|
logger.error("decode(String, Class<T>)", e);
|
|
|
} catch (JsonMappingException e) {
|
|
|
- logger.error(String.format("反序列化失败, 错误原因:%s", e.getMessage()));
|
|
|
+ logger.error(String.format("fromStringJson反序列化失败, 异常类型【JsonMappingException】, 错误原因:{}", e.getMessage()));
|
|
|
logger.error("decode(String, Class<T>)", e);
|
|
|
} catch (IOException e) {
|
|
|
- logger.error(String.format("反序列化失败, 错误原因:%s", e.getMessage()));
|
|
|
+ logger.error(String.format("fromStringJson反序列化失败, 异常类型【IOException】, 错误原因:{}", e.getMessage()));
|
|
|
logger.error("decode(String, Class<T>)", e);
|
|
|
}
|
|
|
return null;
|
|
@@ -232,20 +319,19 @@ public class JacksonUtil {
|
|
|
* @param json
|
|
|
* @return
|
|
|
*/
|
|
|
- public static <T> T fromListJson(String json) {
|
|
|
+ public static <T> T fromListJson(String json, TypeReference<?> typeReference) {
|
|
|
try {
|
|
|
//写成List.class是不行的
|
|
|
- TypeReference<T> jsonTypeReference = new TypeReference<T>(){};
|
|
|
JsonParser jp= getParser(json);
|
|
|
- return (T) jp.readValueAs(jsonTypeReference);
|
|
|
+ return (T) jp.readValueAs(typeReference);
|
|
|
} catch (JsonParseException e) {
|
|
|
- logger.error(String.format("反序列化失败, 错误原因:%s", e.getMessage()));
|
|
|
+ logger.error(String.format("fromListJson反序列化失败, 异常类型【JsonParseException】, 错误原因:{}", e.getMessage()));
|
|
|
logger.error("decode(String, Class<T>)", e);
|
|
|
} catch (JsonMappingException e) {
|
|
|
- logger.error(String.format("反序列化失败, 错误原因:%s", e.getMessage()));
|
|
|
+ logger.error(String.format("fromListJson反序列化失败, 异常类型【JsonMappingException】, 错误原因:{}", e.getMessage()));
|
|
|
logger.error("decode(String, Class<T>)", e);
|
|
|
} catch (IOException e) {
|
|
|
- logger.error(String.format("反序列化失败, 错误原因:%s", e.getMessage()));
|
|
|
+ logger.error(String.format("fromListJson反序列化失败, 异常类型【IOException】, 错误原因:{}", e.getMessage()));
|
|
|
logger.error("decode(String, Class<T>)", e);
|
|
|
}
|
|
|
return null;
|
|
@@ -254,46 +340,13 @@ public class JacksonUtil {
|
|
|
public static void filter(Class<?> clazz , String include , String exclude) {
|
|
|
if (clazz == null) return;
|
|
|
if (include != null && include.length() > 0) {//包含的操作
|
|
|
- mapper.setFilterProvider(new SimpleFilterProvider()
|
|
|
+ objectMapper.setFilterProvider(new SimpleFilterProvider()
|
|
|
.addFilter(DYNC_INCLUDE, SimpleBeanPropertyFilter.filterOutAllExcept(include.split(","))));//多个字段用,分割开
|
|
|
- mapper.addMixIn(clazz, DynamicInclude.class);
|
|
|
+ objectMapper.addMixIn(clazz, DynamicInclude.class);
|
|
|
} else if (exclude != null && exclude.length() > 0) {
|
|
|
- mapper.setFilterProvider(new SimpleFilterProvider()
|
|
|
+ objectMapper.setFilterProvider(new SimpleFilterProvider()
|
|
|
.addFilter(DYNC_EXCLUDE, SimpleBeanPropertyFilter.serializeAllExcept(exclude.split(","))));
|
|
|
- mapper.addMixIn(clazz, DynamicExclude.class);
|
|
|
+ objectMapper.addMixIn(clazz, DynamicExclude.class);
|
|
|
}
|
|
|
}
|
|
|
-
|
|
|
- public static String toJson(Object object) throws JsonProcessingException {
|
|
|
- return mapper.writeValueAsString(object);
|
|
|
- }
|
|
|
- /**
|
|
|
- * Json对象序列化
|
|
|
- */
|
|
|
- public static String toJson1(Object obj){
|
|
|
- StringWriter sw= new StringWriter();
|
|
|
- JsonGenerator jsonGen= getGenerator(sw);
|
|
|
- if (jsonGen== null){
|
|
|
- try {
|
|
|
- sw.close();
|
|
|
- } catch (IOException e) {
|
|
|
- }
|
|
|
- return null;
|
|
|
- }
|
|
|
- try {
|
|
|
- //由于在getGenerator方法中指定了OutputStream为sw
|
|
|
- //因此调用writeObject会将数据输出到sw
|
|
|
- jsonGen.writeObject(obj);
|
|
|
- //由于采用流式输出 在输出完毕后务必清空缓冲区并关闭输出流
|
|
|
- jsonGen.flush();
|
|
|
- jsonGen.close();
|
|
|
- return sw.toString();
|
|
|
- } catch (JsonGenerationException jge) {
|
|
|
- logger.error("Json生成错误" + jge.getMessage());
|
|
|
- } catch (IOException ioe) {
|
|
|
- logger.error("Json输入输出错误" + ioe.getMessage());
|
|
|
- }
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
}
|