Browse Source

fix切换JSON序列化jackson

Eric 1 year ago
parent
commit
37bee8e2df
40 changed files with 3098 additions and 143 deletions
  1. 2 6
      audio-analysis/src/main/java/com/yonge/audio/config/LocalFastJsonHttpMessageConverter.java
  2. 57 7
      audio-analysis/src/main/java/com/yonge/audio/config/WebMvcConfig.java
  3. 3 2
      cooleshow-app/src/main/java/com/yonge/cooleshow/config/WebMvcConfig.java
  4. 1 1
      cooleshow-auth/auth-server/pom.xml
  5. 2 6
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/config/LocalFastJsonHttpMessageConverter.java
  6. 58 8
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/config/WebMvcConfig.java
  7. 302 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/config/jackson/JacksonConfig.java
  8. 63 0
      cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/config/jackson/MappingJSONHttpMessageConverter.java
  9. 2 6
      cooleshow-bbs/src/main/java/com/yonge/cooleshow/bbs/config/LocalFastJsonHttpMessageConverter.java
  10. 53 2
      cooleshow-bbs/src/main/java/com/yonge/cooleshow/bbs/config/WebMvcConfig.java
  11. 302 0
      cooleshow-bbs/src/main/java/com/yonge/cooleshow/bbs/config/jackson/JacksonConfig.java
  12. 58 0
      cooleshow-bbs/src/main/java/com/yonge/cooleshow/bbs/config/jackson/MappingJSONHttpMessageConverter.java
  13. 2 6
      cooleshow-cms/src/main/java/com/yonge/cooleshow/cms/config/LocalFastJsonHttpMessageConverter.java
  14. 57 7
      cooleshow-cms/src/main/java/com/yonge/cooleshow/cms/config/WebMvcConfig.java
  15. 302 0
      cooleshow-cms/src/main/java/com/yonge/cooleshow/cms/config/jackson/JacksonConfig.java
  16. 58 0
      cooleshow-cms/src/main/java/com/yonge/cooleshow/cms/config/jackson/MappingJSONHttpMessageConverter.java
  17. 16 0
      cooleshow-common/src/main/java/com/yonge/cooleshow/common/config/EnumConverterFactory.java
  18. 2 6
      cooleshow-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/config/LocalFastJsonHttpMessageConverter.java
  19. 53 2
      cooleshow-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/config/WebMvcConfig.java
  20. 302 0
      cooleshow-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/config/jackson/JacksonConfig.java
  21. 58 0
      cooleshow-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/config/jackson/MappingJSONHttpMessageConverter.java
  22. 2 3
      cooleshow-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/config/JacksonConfig2.java
  23. 2 6
      cooleshow-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/config/LocalFastJsonHttpMessageConverter.java
  24. 53 2
      cooleshow-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/config/WebMvcConfig.java
  25. 302 0
      cooleshow-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/config/jackson/JacksonConfig.java
  26. 58 0
      cooleshow-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/config/jackson/MappingJSONHttpMessageConverter.java
  27. 2 6
      cooleshow-task/src/main/java/com/yonge/cooleshow/task/config/LocalFastJsonHttpMessageConverter.java
  28. 57 7
      cooleshow-task/src/main/java/com/yonge/cooleshow/task/config/WebMvcConfig.java
  29. 302 0
      cooleshow-task/src/main/java/com/yonge/cooleshow/task/config/jackson/JacksonConfig.java
  30. 58 0
      cooleshow-task/src/main/java/com/yonge/cooleshow/task/config/jackson/MappingJSONHttpMessageConverter.java
  31. 1 1
      cooleshow-user/user-biz/pom.xml
  32. 2 6
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/config/LocalFastJsonHttpMessageConverter.java
  33. 302 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/config/jackson/JacksonConfig.java
  34. 63 0
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/config/jackson/MappingJSONHttpMessageConverter.java
  35. 105 16
      cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseScheduleServiceImpl.java
  36. 1 1
      cooleshow-websocket/pom.xml
  37. 1 1
      pom.xml
  38. 1 1
      toolset/utils/pom.xml
  39. 20 21
      toolset/utils/src/main/java/com/yonge/toolset/utils/http/HttpUtil.java
  40. 13 13
      toolset/utils/src/main/java/com/yonge/toolset/utils/json/JsonUtil.java

+ 2 - 6
audio-analysis/src/main/java/com/yonge/audio/config/LocalFastJsonHttpMessageConverter.java

@@ -2,12 +2,10 @@ package com.yonge.audio.config;
 
 import com.alibaba.fastjson.serializer.JSONSerializer;
 import com.alibaba.fastjson.serializer.ObjectSerializer;
-import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
 import com.alibaba.fastjson.serializer.ValueFilter;
 import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
 import com.vdurmont.emoji.EmojiParser;
 import com.yonge.toolset.base.enums.BaseEnum;
-import com.yonge.toolset.utils.json.JsonUtil;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.http.HttpInputMessage;
 import org.springframework.http.HttpOutputMessage;
@@ -15,10 +13,8 @@ import org.springframework.http.converter.HttpMessageNotReadableException;
 import org.springframework.http.converter.HttpMessageNotWritableException;
 
 import java.io.IOException;
-import java.io.OutputStream;
 import java.lang.reflect.Type;
 import java.math.BigDecimal;
-import java.util.Date;
 
 public class LocalFastJsonHttpMessageConverter extends FastJsonHttpMessageConverter {
 
@@ -32,12 +28,12 @@ public class LocalFastJsonHttpMessageConverter extends FastJsonHttpMessageConver
 	@Override
 	protected void writeInternal(Object obj, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
 
-		OutputStream out = outputMessage.getBody();
+		/*OutputStream out = outputMessage.getBody();
 		JsonUtil.getConfig().put(Date.class, new SimpleDateFormatSerializer(FORMAT));
 		//JsonUtil.getConfig().put(String.class, new EmojiSerializer());
 		String text = JsonUtil.toJSONString(obj, EnumFilter.instance, getFeatures());
 		byte[] bytes = text.getBytes(getCharset());
-		out.write(bytes);
+		out.write(bytes);*/
 	}
 }
 

+ 57 - 7
audio-analysis/src/main/java/com/yonge/audio/config/WebMvcConfig.java

@@ -1,16 +1,22 @@
 package com.yonge.audio.config;
 
-import java.util.ArrayList;
-import java.util.List;
-
+import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
+import com.google.common.collect.Lists;
+import com.yonge.cooleshow.biz.dal.config.jackson.JacksonConfig;
+import com.yonge.cooleshow.biz.dal.config.jackson.MappingJSONHttpMessageConverter;
+import com.yonge.cooleshow.common.config.EnumConverterFactory;
 import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
-import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
 import org.springframework.format.FormatterRegistry;
 import org.springframework.http.MediaType;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.StringHttpMessageConverter;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 
-import com.yonge.cooleshow.common.config.EnumConverterFactory;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
 
 @Configuration
 public class WebMvcConfig implements WebMvcConfigurer {
@@ -20,10 +26,54 @@ public class WebMvcConfig implements WebMvcConfigurer {
 	 */
 	@Override
 	public void addFormatters(FormatterRegistry registry) {
+		// 枚举转换器
 		registry.addConverterFactory(new EnumConverterFactory());
+		// 字符串时间转换器
+		registry.addConverter(new JacksonConfig.CustomStringDateConverter());
 	}
-	
-	@Bean
+
+	/**
+	 * @param converters List<HttpMessageConverter<?>>
+	 */
+	@Override
+	public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
+		//WebMvcConfigurer.super.configureMessageConverters(converters);
+
+		// 如果存在fastJson的转换器,将其移除
+		converters.removeIf(httpMessageConverter -> httpMessageConverter instanceof FastJsonHttpMessageConverter);
+
+		// 需要重新加入jackson的转换器,该处的objectMapper已经在配置中注册了
+		MappingJSONHttpMessageConverter converter = new MappingJSONHttpMessageConverter(new JacksonConfig.JacksonObjectMapper());
+		converter.setDefaultCharset(StandardCharsets.UTF_8); // 字符编号
+		converters.add(0, converter);
+
+		// 添加String转换器
+		converters.add(utf8StringHttpMessageConverter());
+	}
+
+	/**
+	 * 自定义String转换器
+	 * @return HttpMessageConverters
+	 */
+	//@Bean
+	@Primary
+	public StringHttpMessageConverter utf8StringHttpMessageConverter() {
+
+		StringHttpMessageConverter converter = new StringHttpMessageConverter();
+
+		List<MediaType> mediaTypes = Lists.newArrayList();
+		mediaTypes.add(MediaType.TEXT_HTML);
+		mediaTypes.add(MediaType.TEXT_PLAIN);
+		mediaTypes.add(MediaType.TEXT_XML);
+		mediaTypes.add(MediaType.APPLICATION_XML);
+
+		converter.setSupportedMediaTypes(mediaTypes);
+		converter.setDefaultCharset(StandardCharsets.UTF_8);
+
+		return converter;
+	}
+
+	//@Bean
     public HttpMessageConverters fastJsonHttpMessageConverters(){
 		LocalFastJsonHttpMessageConverter converter = new LocalFastJsonHttpMessageConverter();
         List<MediaType> fastMediaTypes =  new ArrayList<MediaType>();

+ 3 - 2
cooleshow-app/src/main/java/com/yonge/cooleshow/config/WebMvcConfig.java

@@ -2,8 +2,9 @@ package com.yonge.cooleshow.config;
 
 import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
 import com.google.common.collect.Lists;
-import com.microsvc.toolkit.common.webportal.converter.MappingJSONHttpMessageConverter;
 import com.yonge.cooleshow.biz.dal.config.LocalFastJsonHttpMessageConverter;
+import com.yonge.cooleshow.biz.dal.config.jackson.JacksonConfig;
+import com.yonge.cooleshow.biz.dal.config.jackson.MappingJSONHttpMessageConverter;
 import com.yonge.cooleshow.common.config.EnumConverterFactory;
 import com.yonge.cooleshow.interceptor.MDCInterceptor;
 import com.yonge.cooleshow.interceptor.OperationLogInterceptor;
@@ -63,7 +64,7 @@ public class WebMvcConfig implements WebMvcConfigurer {
 		converters.removeIf(httpMessageConverter -> httpMessageConverter instanceof FastJsonHttpMessageConverter);
 
 		// 需要重新加入jackson的转换器,该处的objectMapper已经在配置中注册了
-		com.microsvc.toolkit.common.webportal.converter.MappingJSONHttpMessageConverter converter = new MappingJSONHttpMessageConverter(new JacksonConfig.JacksonObjectMapper());
+		MappingJSONHttpMessageConverter converter = new MappingJSONHttpMessageConverter(new JacksonConfig.JacksonObjectMapper());
 		converter.setDefaultCharset(StandardCharsets.UTF_8); // 字符编号
 		converters.add(0, converter);
 

+ 1 - 1
cooleshow-auth/auth-server/pom.xml

@@ -33,7 +33,7 @@
         <dependency>
             <groupId>com.alibaba</groupId>
             <artifactId>fastjson</artifactId>
-            <version>1.2.79</version>
+            <version>2.0.9</version>
         </dependency>
 
         <dependency>

+ 2 - 6
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/config/LocalFastJsonHttpMessageConverter.java

@@ -2,12 +2,10 @@ package com.yonge.cooleshow.auth.config;
 
 import com.alibaba.fastjson.serializer.JSONSerializer;
 import com.alibaba.fastjson.serializer.ObjectSerializer;
-import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
 import com.alibaba.fastjson.serializer.ValueFilter;
 import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
 import com.vdurmont.emoji.EmojiParser;
 import com.yonge.toolset.base.enums.BaseEnum;
-import com.yonge.toolset.utils.json.JsonUtil;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.http.HttpInputMessage;
 import org.springframework.http.HttpOutputMessage;
@@ -15,10 +13,8 @@ import org.springframework.http.converter.HttpMessageNotReadableException;
 import org.springframework.http.converter.HttpMessageNotWritableException;
 
 import java.io.IOException;
-import java.io.OutputStream;
 import java.lang.reflect.Type;
 import java.math.BigDecimal;
-import java.util.Date;
 
 public class LocalFastJsonHttpMessageConverter extends FastJsonHttpMessageConverter {
 
@@ -32,12 +28,12 @@ public class LocalFastJsonHttpMessageConverter extends FastJsonHttpMessageConver
 	@Override
 	protected void writeInternal(Object obj, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
 
-		OutputStream out = outputMessage.getBody();
+		/*OutputStream out = outputMessage.getBody();
 		JsonUtil.getConfig().put(Date.class, new SimpleDateFormatSerializer(FORMAT));
 		//JsonUtil.getConfig().put(String.class, new EmojiSerializer());
 		String text = JsonUtil.toJSONString(obj, EnumFilter.instance, getFeatures());
 		byte[] bytes = text.getBytes(getCharset());
-		out.write(bytes);
+		out.write(bytes);*/
 	}
 }
 

+ 58 - 8
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/config/WebMvcConfig.java

@@ -1,19 +1,25 @@
 package com.yonge.cooleshow.auth.config;
 
-import java.util.ArrayList;
-import java.util.List;
-
+import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
+import com.google.common.collect.Lists;
+import com.yonge.cooleshow.auth.config.jackson.JacksonConfig;
+import com.yonge.cooleshow.auth.config.jackson.MappingJSONHttpMessageConverter;
+import com.yonge.cooleshow.auth.interceptor.OperationLogInterceptor;
+import com.yonge.cooleshow.common.config.EnumConverterFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
-import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
 import org.springframework.format.FormatterRegistry;
 import org.springframework.http.MediaType;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.StringHttpMessageConverter;
 import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 
-import com.yonge.cooleshow.auth.interceptor.OperationLogInterceptor;
-import com.yonge.cooleshow.common.config.EnumConverterFactory;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
 
 @Configuration
 public class WebMvcConfig implements WebMvcConfigurer {
@@ -26,15 +32,59 @@ public class WebMvcConfig implements WebMvcConfigurer {
 	 */
 	@Override
 	public void addFormatters(FormatterRegistry registry) {
+		// 枚举转换器
 		registry.addConverterFactory(new EnumConverterFactory());
+		// 字符串时间转换器
+		registry.addConverter(new JacksonConfig.CustomStringDateConverter());
 	}
 	
 	@Override
 	public void addInterceptors(InterceptorRegistry registry) {
 		registry.addInterceptor(operationLogInterceptor).addPathPatterns("/userDevice/unbind").excludePathPatterns("/*");
 	}
-	
-	@Bean
+
+	/**
+	 * @param converters List<HttpMessageConverter<?>>
+	 */
+	@Override
+	public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
+		//WebMvcConfigurer.super.configureMessageConverters(converters);
+
+		// 如果存在fastJson的转换器,将其移除
+		converters.removeIf(httpMessageConverter -> httpMessageConverter instanceof FastJsonHttpMessageConverter);
+
+		// 需要重新加入jackson的转换器,该处的objectMapper已经在配置中注册了
+		MappingJSONHttpMessageConverter converter = new MappingJSONHttpMessageConverter(new JacksonConfig.JacksonObjectMapper());
+		converter.setDefaultCharset(StandardCharsets.UTF_8); // 字符编号
+		converters.add(0, converter);
+
+		// 添加String转换器
+		converters.add(utf8StringHttpMessageConverter());
+	}
+
+	/**
+	 * 自定义String转换器
+	 * @return HttpMessageConverters
+	 */
+	//@Bean
+	@Primary
+	public StringHttpMessageConverter utf8StringHttpMessageConverter() {
+
+		StringHttpMessageConverter converter = new StringHttpMessageConverter();
+
+		List<MediaType> mediaTypes = Lists.newArrayList();
+		mediaTypes.add(MediaType.TEXT_HTML);
+		mediaTypes.add(MediaType.TEXT_PLAIN);
+		mediaTypes.add(MediaType.TEXT_XML);
+		mediaTypes.add(MediaType.APPLICATION_XML);
+
+		converter.setSupportedMediaTypes(mediaTypes);
+		converter.setDefaultCharset(StandardCharsets.UTF_8);
+
+		return converter;
+	}
+
+	//@Bean
     public HttpMessageConverters fastJsonHttpMessageConverters(){
 		LocalFastJsonHttpMessageConverter converter = new LocalFastJsonHttpMessageConverter();
         List<MediaType> fastMediaTypes =  new ArrayList<MediaType>();

+ 302 - 0
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/config/jackson/JacksonConfig.java

@@ -0,0 +1,302 @@
+package com.yonge.cooleshow.auth.config.jackson;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.BeanProperty;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
+import com.fasterxml.jackson.databind.deser.std.DateDeserializers;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.databind.ser.std.DateSerializer;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
+import com.yonge.cooleshow.common.config.EnumConverterFactory;
+import com.yonge.toolset.base.enums.BaseEnum;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
+import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.util.StringUtils;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.RoundingMode;
+import java.text.DecimalFormat;
+import java.text.SimpleDateFormat;
+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;
+import java.util.TimeZone;
+
+/**
+ * JSON LocalDateTime 序列化、反序列化配置
+ */
+@Configuration
+@ConditionalOnClass(ObjectMapper.class)
+@AutoConfigureBefore(JacksonAutoConfiguration.class)
+public class JacksonConfig {
+
+    public static final String NORM_DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss"; // 时间格式
+    public static final String NORM_DATE_PATTERN = "yyyy-MM-dd";
+    public static final String NORM_TIME_PATTERN = "HH:mm:ss";
+    //public static final String NORM_TIME_ZONE = "GMT+8"; // 时区设置
+    /**
+     * 时区配置
+     */
+    @Bean
+    public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() {
+        return builder -> {
+
+            // 配置Date的格式化
+            builder.locale(Locale.CHINA);
+            builder.timeZone(TimeZone.getTimeZone("Asia/Shanghai"));
+            builder.simpleDateFormat(NORM_DATETIME_PATTERN);
+
+            // 配置Jackson转换配置
+            //builder.configure(new JacksonObjectMapper());
+
+            //builder.serializationInclusion(JsonInclude.Include.USE_DEFAULTS);
+        };
+    }
+
+    /**
+     * 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象
+     * 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]
+     * 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]
+     */
+    public static class JacksonObjectMapper extends ObjectMapper {
+
+        public JacksonObjectMapper() {
+            super();
+            //反序列化的时候如果多了其他属性,不抛出异常
+            this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
+                    //.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true)
+                    //不注释,会导致swagger报错
+                    //.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL)
+                    //关闭日期序列化为时间戳的功能
+                    //.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
+                    //关闭序列化的时候没有为属性找到getter方法,报错
+                    //.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS)
+                    //关闭反序列化的时候,没有找到属性的setter报错
+                    //.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
+                    //序列化的时候序列对象的所有属性
+                    //.setSerializationInclusion(JsonInclude.Include.ALWAYS)
+                    //如果是空对象的时候,不抛异常
+                    //.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
+                    //反序列化时,属性不存在的兼容处理
+                    //.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
+                    .setDateFormat(new SimpleDateFormat(NORM_DATETIME_PATTERN, Locale.SIMPLIFIED_CHINESE))
+                    .setLocale(Locale.CHINA)
+                    .setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
+
+                    SimpleModule simpleModule = new SimpleModule()
+                    // 时间对象反序列化
+                    .addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(NORM_DATETIME_PATTERN)))
+                    .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(NORM_DATE_PATTERN)))
+                    .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(NORM_TIME_PATTERN)))
+                    .addDeserializer(Date.class,new DateDeserializers.DateDeserializer(DateDeserializers.DateDeserializer.instance,
+                            new SimpleDateFormat(NORM_DATETIME_PATTERN), NORM_DATETIME_PATTERN))
+
+                    // 时间对象序列化
+                    .addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(NORM_DATETIME_PATTERN)))
+                    .addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(NORM_DATE_PATTERN)))
+                    .addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(NORM_TIME_PATTERN)))
+                    .addSerializer(Date.class, new DateSerializer(false, new SimpleDateFormat(NORM_DATETIME_PATTERN)))
+
+                     // 枚举类序列化
+                    .addDeserializer(Enum.class, new BaseEnumDeserializer())
+                    .addSerializer(BaseEnum.class, new BaseEnumSerializer())
+
+                    // Long对象转String
+                    //.addSerializer(Float.class, new FloatJsonSerializer())
+                    //.addSerializer(Float.TYPE, new FloatJsonSerializer())
+
+                    .addSerializer(Long.class, ToStringSerializer.instance)
+                    .addSerializer(Long.TYPE, ToStringSerializer.instance)
+
+                    .addSerializer(BigDecimal.class, new BigDecimalJsonSerializer())
+                    .addSerializer(BigInteger.class, ToStringSerializer.instance)
+
+                    .addSerializer(Double.class, new DoubleJsonSerializer())
+                    .addSerializer(Double.TYPE, new DoubleJsonSerializer());
+
+            //注册功能模块 例如,可以添加自定义序列化器和反序列化器
+            this.registerModule(simpleModule);
+        }
+    }
+
+    /**
+     * Double精度处理
+     * #@JsonSerialize(using = JacksonConvertConfig.DoubleJsonSerializer.class)
+     */
+    public static class DoubleJsonSerializer extends JsonSerializer<Double> {
+
+        @Override
+        public void serialize(Double arg0, JsonGenerator arg1, SerializerProvider arg2) throws IOException {
+            if(arg0 != null) {
+                getJsonConvertValue(arg1, new BigDecimal(String.valueOf(arg0)));
+            }
+        }
+    }
+
+    /**
+     * JSON数据转换
+     * @param arg1 JsonGenerator
+     * @param bigDecimal BigDecimal
+     * @throws IOException IOException
+     */
+    private static void getJsonConvertValue(JsonGenerator arg1, BigDecimal bigDecimal) throws IOException {
+
+        // 原本这里是  ##.00 ,带来的问题是如果数据库数据为0.00返回“ .00 “经评论指正,改为0.00
+        DecimalFormat decimalFormat = new DecimalFormat("#.00");
+
+        decimalFormat.setRoundingMode(RoundingMode.HALF_UP);
+        //四舍五入。需要将数据转成bigDecimal, 否则会存在经度丢失问题
+        String format = decimalFormat.format(bigDecimal);
+
+        arg1.writeNumber(new BigDecimal(format));//返回数字格式
+    }
+
+    /**
+     * BigDecimal精度处理
+     * #@JsonSerialize(using = JacksonConvertConfig.BigDecimalJsonSerializer.class)
+     */
+    public static class BigDecimalJsonSerializer extends JsonSerializer<BigDecimal> {
+
+        @Override
+        public void serialize(BigDecimal arg0, JsonGenerator arg1, SerializerProvider arg2) throws IOException {
+            if(arg0 != null) {
+                getJsonConvertValue(arg1, arg0);
+            }
+        }
+    }
+
+    /**
+     * Float精度处理
+     * #@JsonSerialize(using = JacksonConvertConfig.FloatJsonSerializer.class)
+     */
+    public static class FloatJsonSerializer extends JsonSerializer<Float> {
+
+        @Override
+        public void serialize(Float arg0, JsonGenerator arg1, SerializerProvider arg2) throws IOException {
+            if(arg0 != null) {
+                getJsonConvertValue(arg1, new BigDecimal(String.valueOf(arg0)));
+            }
+        }
+    }
+
+    /**
+     * 枚举类反序列化
+     */
+    @Data
+    @EqualsAndHashCode(callSuper = true)
+    public static class BaseEnumDeserializer extends JsonDeserializer<Enum<?>> implements ContextualDeserializer {
+
+        private Class<?> target;
+
+        @SuppressWarnings("all")
+        @Override
+        public Enum<?> deserialize(JsonParser jsonParser, DeserializationContext ctx) throws IOException {
+            if (!StringUtils.hasText(jsonParser.getText())) {
+                return null;
+            }
+
+            if (BaseEnum.class.isAssignableFrom(target)) {
+                return (Enum<?>) EnumConverterFactory.getEnum((Class) target, jsonParser.getText());
+            }
+            return null;
+        }
+
+        /**
+         * @param ctx      DeserializationContext
+         * @param property BeanProperty
+         * @return JsonDeserializer
+         */
+        @Override
+        public JsonDeserializer<?> createContextual(DeserializationContext ctx, BeanProperty property) {
+            Class<?> rawCls = ctx.getContextualType().getRawClass();
+            BaseEnumDeserializer enumDeserializer = new BaseEnumDeserializer();
+            enumDeserializer.setTarget(rawCls);
+            return enumDeserializer;
+        }
+
+    }
+
+    /**
+     * 枚举类序列化
+     */
+    public static class BaseEnumSerializer extends JsonSerializer<BaseEnum> {
+
+        @Override
+        public void serialize(BaseEnum enums, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
+
+            if (enums.getCode() instanceof Integer) {
+                // 返回整形
+                jsonGenerator.writeNumber(Integer.parseInt(String.valueOf(enums.getCode())));
+            } else {
+                // 返回字符串
+                jsonGenerator.writeString(String.valueOf(enums.getCode()));
+            }
+        }
+    }
+
+    /**
+     * 字符串格式转日期
+     */
+    public static class CustomStringDateConverter implements Converter<String, Date> {
+        private static final String dateFormat = "yyyy-MM-dd HH:mm:ss";
+        private static final String shortDateFormat = "yyyy-MM-dd";
+        private static final String dateFormat2 = "yyyy/MM/dd HH:mm:ss";
+        private static final String shortDateFormat2 = "yyyy/MM/dd";
+
+        @Override
+        public Date convert(String source) {
+            if (org.apache.commons.lang3.StringUtils.isBlank(source)) {
+                return null;
+            }
+            source = source.trim();
+            try {
+                SimpleDateFormat formatter;
+                if (source.contains("-")) {
+                    if (source.contains(":")) {
+                        formatter = new SimpleDateFormat(dateFormat);
+                    } else {
+                        formatter = new SimpleDateFormat(shortDateFormat);
+                    }
+                    return formatter.parse(source);
+                } else if (source.contains("/")) {
+                    if (source.contains(":")) {
+                        formatter = new SimpleDateFormat(dateFormat2);
+                    } else {
+                        formatter = new SimpleDateFormat(shortDateFormat2);
+                    }
+                    return formatter.parse(source);
+                }
+            } catch (Exception e) {
+                throw new RuntimeException(String.format("parser %s to Date fail", source));
+            }
+
+            throw new RuntimeException(String.format("parser %s to Date fail", source));
+        }
+    }
+
+}

+ 63 - 0
cooleshow-auth/auth-server/src/main/java/com/yonge/cooleshow/auth/config/jackson/MappingJSONHttpMessageConverter.java

@@ -0,0 +1,63 @@
+package com.yonge.cooleshow.auth.config.jackson;
+
+import com.alibaba.fastjson.JSON;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.microsvc.toolkit.common.response.template.ExtResponse;
+import com.microsvc.toolkit.common.response.template.JSONResponse;
+import com.microsvc.toolkit.common.response.template.Response;
+import com.microsvc.toolkit.common.response.template.SysResponse;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpOutputMessage;
+import org.springframework.http.converter.HttpMessageNotWritableException;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+
+import java.io.IOException;
+import java.lang.reflect.Type;
+
+/**
+ * Created by Eric.Shang on 3/3/17.
+ */
+@Slf4j
+public class MappingJSONHttpMessageConverter extends MappingJackson2HttpMessageConverter {
+
+    public MappingJSONHttpMessageConverter() {
+    }
+
+    public MappingJSONHttpMessageConverter(ObjectMapper objectMapper) {
+        super(objectMapper);
+    }
+
+    /**
+     * 自定义JSON异常封装
+     * @param object Object
+     * @param type Type
+     * @param outputMessage HttpOutputMessage
+     * @throws IOException IOException
+     * @throws HttpMessageNotWritableException HttpMessageNotWritableException
+     */
+    @Override
+    protected void writeInternal(Object object, Type type, HttpOutputMessage outputMessage)
+            throws IOException, HttpMessageNotWritableException {
+
+        try {
+
+            if (object instanceof ExtResponse) {
+                // 拓展返回数据结构
+                object = ((ExtResponse<?>) object).data();
+
+            } else if (object instanceof Response) {
+                // 自定义标准数据结构
+                object = SysResponse.from((Response<?>) object);
+
+            } else if (object instanceof JSONResponse) {
+                // 三方标准数据结构,
+                object = JSON.toJSON(object);
+            }
+
+        } catch (Exception e) {
+            object = SysResponse.sysResponse();
+            log.error("jsonObject={}", object, e);
+        }
+        super.writeInternal(object, type, outputMessage);
+    }
+}

+ 2 - 6
cooleshow-bbs/src/main/java/com/yonge/cooleshow/bbs/config/LocalFastJsonHttpMessageConverter.java

@@ -2,12 +2,10 @@ package com.yonge.cooleshow.bbs.config;
 
 import com.alibaba.fastjson.serializer.JSONSerializer;
 import com.alibaba.fastjson.serializer.ObjectSerializer;
-import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
 import com.alibaba.fastjson.serializer.ValueFilter;
 import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
 import com.vdurmont.emoji.EmojiParser;
 import com.yonge.toolset.base.enums.BaseEnum;
-import com.yonge.toolset.utils.json.JsonUtil;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.http.HttpInputMessage;
 import org.springframework.http.HttpOutputMessage;
@@ -15,10 +13,8 @@ import org.springframework.http.converter.HttpMessageNotReadableException;
 import org.springframework.http.converter.HttpMessageNotWritableException;
 
 import java.io.IOException;
-import java.io.OutputStream;
 import java.lang.reflect.Type;
 import java.math.BigDecimal;
-import java.util.Date;
 
 public class LocalFastJsonHttpMessageConverter extends FastJsonHttpMessageConverter {
 
@@ -32,12 +28,12 @@ public class LocalFastJsonHttpMessageConverter extends FastJsonHttpMessageConver
 	@Override
 	protected void writeInternal(Object obj, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
 
-		OutputStream out = outputMessage.getBody();
+		/*OutputStream out = outputMessage.getBody();
 		JsonUtil.getConfig().put(Date.class, new SimpleDateFormatSerializer(FORMAT));
 		//JsonUtil.getConfig().put(String.class, new EmojiSerializer());
 		String text = JsonUtil.toJSONString(obj, EnumFilter.instance, getFeatures());
 		byte[] bytes = text.getBytes(getCharset());
-		out.write(bytes);
+		out.write(bytes);*/
 	}
 }
 

+ 53 - 2
cooleshow-bbs/src/main/java/com/yonge/cooleshow/bbs/config/WebMvcConfig.java

@@ -1,14 +1,21 @@
 package com.yonge.cooleshow.bbs.config;
 
+import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
+import com.google.common.collect.Lists;
+import com.yonge.cooleshow.bbs.config.jackson.JacksonConfig;
+import com.yonge.cooleshow.bbs.config.jackson.MappingJSONHttpMessageConverter;
 import com.yonge.cooleshow.common.config.EnumConverterFactory;
 import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
-import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
 import org.springframework.format.FormatterRegistry;
 import org.springframework.http.MediaType;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.StringHttpMessageConverter;
 import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -21,7 +28,10 @@ public class WebMvcConfig implements WebMvcConfigurer {
 	 */
 	@Override
 	public void addFormatters(FormatterRegistry registry) {
+		// 枚举转换器
 		registry.addConverterFactory(new EnumConverterFactory());
+		// 字符串时间转换器
+		registry.addConverter(new JacksonConfig.CustomStringDateConverter());
 	}
 
 	@Override
@@ -39,7 +49,48 @@ public class WebMvcConfig implements WebMvcConfigurer {
 //		registry.addInterceptor(operationLogInterceptor).addPathPatterns("/**").excludePathPatterns("/login");
 	}
 
-	@Bean
+	/**
+	 * @param converters List<HttpMessageConverter<?>>
+	 */
+	@Override
+	public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
+		//WebMvcConfigurer.super.configureMessageConverters(converters);
+
+		// 如果存在fastJson的转换器,将其移除
+		converters.removeIf(httpMessageConverter -> httpMessageConverter instanceof FastJsonHttpMessageConverter);
+
+		// 需要重新加入jackson的转换器,该处的objectMapper已经在配置中注册了
+		MappingJSONHttpMessageConverter converter = new MappingJSONHttpMessageConverter(new JacksonConfig.JacksonObjectMapper());
+		converter.setDefaultCharset(StandardCharsets.UTF_8); // 字符编号
+		converters.add(0, converter);
+
+		// 添加String转换器
+		converters.add(utf8StringHttpMessageConverter());
+	}
+
+	/**
+	 * 自定义String转换器
+	 * @return HttpMessageConverters
+	 */
+	//@Bean
+	@Primary
+	public StringHttpMessageConverter utf8StringHttpMessageConverter() {
+
+		StringHttpMessageConverter converter = new StringHttpMessageConverter();
+
+		List<MediaType> mediaTypes = Lists.newArrayList();
+		mediaTypes.add(MediaType.TEXT_HTML);
+		mediaTypes.add(MediaType.TEXT_PLAIN);
+		mediaTypes.add(MediaType.TEXT_XML);
+		mediaTypes.add(MediaType.APPLICATION_XML);
+
+		converter.setSupportedMediaTypes(mediaTypes);
+		converter.setDefaultCharset(StandardCharsets.UTF_8);
+
+		return converter;
+	}
+
+	//@Bean
 	public HttpMessageConverters fastJsonHttpMessageConverters() {
 		LocalFastJsonHttpMessageConverter converter = new LocalFastJsonHttpMessageConverter();
 		List<MediaType> fastMediaTypes = new ArrayList<MediaType>();

+ 302 - 0
cooleshow-bbs/src/main/java/com/yonge/cooleshow/bbs/config/jackson/JacksonConfig.java

@@ -0,0 +1,302 @@
+package com.yonge.cooleshow.bbs.config.jackson;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.BeanProperty;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
+import com.fasterxml.jackson.databind.deser.std.DateDeserializers;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.databind.ser.std.DateSerializer;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
+import com.yonge.cooleshow.common.config.EnumConverterFactory;
+import com.yonge.toolset.base.enums.BaseEnum;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
+import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.util.StringUtils;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.RoundingMode;
+import java.text.DecimalFormat;
+import java.text.SimpleDateFormat;
+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;
+import java.util.TimeZone;
+
+/**
+ * JSON LocalDateTime 序列化、反序列化配置
+ */
+@Configuration
+@ConditionalOnClass(ObjectMapper.class)
+@AutoConfigureBefore(JacksonAutoConfiguration.class)
+public class JacksonConfig {
+
+    public static final String NORM_DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss"; // 时间格式
+    public static final String NORM_DATE_PATTERN = "yyyy-MM-dd";
+    public static final String NORM_TIME_PATTERN = "HH:mm:ss";
+    //public static final String NORM_TIME_ZONE = "GMT+8"; // 时区设置
+    /**
+     * 时区配置
+     */
+    @Bean
+    public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() {
+        return builder -> {
+
+            // 配置Date的格式化
+            builder.locale(Locale.CHINA);
+            builder.timeZone(TimeZone.getTimeZone("Asia/Shanghai"));
+            builder.simpleDateFormat(NORM_DATETIME_PATTERN);
+
+            // 配置Jackson转换配置
+            //builder.configure(new JacksonObjectMapper());
+
+            //builder.serializationInclusion(JsonInclude.Include.USE_DEFAULTS);
+        };
+    }
+
+    /**
+     * 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象
+     * 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]
+     * 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]
+     */
+    public static class JacksonObjectMapper extends ObjectMapper {
+
+        public JacksonObjectMapper() {
+            super();
+            //反序列化的时候如果多了其他属性,不抛出异常
+            this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
+                    //.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true)
+                    //不注释,会导致swagger报错
+                    //.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL)
+                    //关闭日期序列化为时间戳的功能
+                    //.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
+                    //关闭序列化的时候没有为属性找到getter方法,报错
+                    //.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS)
+                    //关闭反序列化的时候,没有找到属性的setter报错
+                    //.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
+                    //序列化的时候序列对象的所有属性
+                    //.setSerializationInclusion(JsonInclude.Include.ALWAYS)
+                    //如果是空对象的时候,不抛异常
+                    //.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
+                    //反序列化时,属性不存在的兼容处理
+                    //.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
+                    .setDateFormat(new SimpleDateFormat(NORM_DATETIME_PATTERN, Locale.SIMPLIFIED_CHINESE))
+                    .setLocale(Locale.CHINA)
+                    .setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
+
+                    SimpleModule simpleModule = new SimpleModule()
+                    // 时间对象反序列化
+                    .addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(NORM_DATETIME_PATTERN)))
+                    .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(NORM_DATE_PATTERN)))
+                    .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(NORM_TIME_PATTERN)))
+                    .addDeserializer(Date.class,new DateDeserializers.DateDeserializer(DateDeserializers.DateDeserializer.instance,
+                            new SimpleDateFormat(NORM_DATETIME_PATTERN), NORM_DATETIME_PATTERN))
+
+                    // 时间对象序列化
+                    .addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(NORM_DATETIME_PATTERN)))
+                    .addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(NORM_DATE_PATTERN)))
+                    .addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(NORM_TIME_PATTERN)))
+                    .addSerializer(Date.class, new DateSerializer(false, new SimpleDateFormat(NORM_DATETIME_PATTERN)))
+
+                     // 枚举类序列化
+                    .addDeserializer(Enum.class, new BaseEnumDeserializer())
+                    .addSerializer(BaseEnum.class, new BaseEnumSerializer())
+
+                    // Long对象转String
+                    //.addSerializer(Float.class, new FloatJsonSerializer())
+                    //.addSerializer(Float.TYPE, new FloatJsonSerializer())
+
+                    .addSerializer(Long.class, ToStringSerializer.instance)
+                    .addSerializer(Long.TYPE, ToStringSerializer.instance)
+
+                    .addSerializer(BigDecimal.class, new BigDecimalJsonSerializer())
+                    .addSerializer(BigInteger.class, ToStringSerializer.instance)
+
+                    .addSerializer(Double.class, new DoubleJsonSerializer())
+                    .addSerializer(Double.TYPE, new DoubleJsonSerializer());
+
+            //注册功能模块 例如,可以添加自定义序列化器和反序列化器
+            this.registerModule(simpleModule);
+        }
+    }
+
+    /**
+     * Double精度处理
+     * #@JsonSerialize(using = JacksonConvertConfig.DoubleJsonSerializer.class)
+     */
+    public static class DoubleJsonSerializer extends JsonSerializer<Double> {
+
+        @Override
+        public void serialize(Double arg0, JsonGenerator arg1, SerializerProvider arg2) throws IOException {
+            if(arg0 != null) {
+                getJsonConvertValue(arg1, new BigDecimal(String.valueOf(arg0)));
+            }
+        }
+    }
+
+    /**
+     * JSON数据转换
+     * @param arg1 JsonGenerator
+     * @param bigDecimal BigDecimal
+     * @throws IOException IOException
+     */
+    private static void getJsonConvertValue(JsonGenerator arg1, BigDecimal bigDecimal) throws IOException {
+
+        // 原本这里是  ##.00 ,带来的问题是如果数据库数据为0.00返回“ .00 “经评论指正,改为0.00
+        DecimalFormat decimalFormat = new DecimalFormat("#.00");
+
+        decimalFormat.setRoundingMode(RoundingMode.HALF_UP);
+        //四舍五入。需要将数据转成bigDecimal, 否则会存在经度丢失问题
+        String format = decimalFormat.format(bigDecimal);
+
+        arg1.writeNumber(new BigDecimal(format));//返回数字格式
+    }
+
+    /**
+     * BigDecimal精度处理
+     * #@JsonSerialize(using = JacksonConvertConfig.BigDecimalJsonSerializer.class)
+     */
+    public static class BigDecimalJsonSerializer extends JsonSerializer<BigDecimal> {
+
+        @Override
+        public void serialize(BigDecimal arg0, JsonGenerator arg1, SerializerProvider arg2) throws IOException {
+            if(arg0 != null) {
+                getJsonConvertValue(arg1, arg0);
+            }
+        }
+    }
+
+    /**
+     * Float精度处理
+     * #@JsonSerialize(using = JacksonConvertConfig.FloatJsonSerializer.class)
+     */
+    public static class FloatJsonSerializer extends JsonSerializer<Float> {
+
+        @Override
+        public void serialize(Float arg0, JsonGenerator arg1, SerializerProvider arg2) throws IOException {
+            if(arg0 != null) {
+                getJsonConvertValue(arg1, new BigDecimal(String.valueOf(arg0)));
+            }
+        }
+    }
+
+    /**
+     * 枚举类反序列化
+     */
+    @Data
+    @EqualsAndHashCode(callSuper = true)
+    public static class BaseEnumDeserializer extends JsonDeserializer<Enum<?>> implements ContextualDeserializer {
+
+        private Class<?> target;
+
+        @SuppressWarnings("all")
+        @Override
+        public Enum<?> deserialize(JsonParser jsonParser, DeserializationContext ctx) throws IOException {
+            if (!StringUtils.hasText(jsonParser.getText())) {
+                return null;
+            }
+
+            if (BaseEnum.class.isAssignableFrom(target)) {
+                return (Enum<?>) EnumConverterFactory.getEnum((Class) target, jsonParser.getText());
+            }
+            return null;
+        }
+
+        /**
+         * @param ctx      DeserializationContext
+         * @param property BeanProperty
+         * @return JsonDeserializer
+         */
+        @Override
+        public JsonDeserializer<?> createContextual(DeserializationContext ctx, BeanProperty property) {
+            Class<?> rawCls = ctx.getContextualType().getRawClass();
+            BaseEnumDeserializer enumDeserializer = new BaseEnumDeserializer();
+            enumDeserializer.setTarget(rawCls);
+            return enumDeserializer;
+        }
+
+    }
+
+    /**
+     * 枚举类序列化
+     */
+    public static class BaseEnumSerializer extends JsonSerializer<BaseEnum> {
+
+        @Override
+        public void serialize(BaseEnum enums, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
+
+            if (enums.getCode() instanceof Integer) {
+                // 返回整形
+                jsonGenerator.writeNumber(Integer.parseInt(String.valueOf(enums.getCode())));
+            } else {
+                // 返回字符串
+                jsonGenerator.writeString(String.valueOf(enums.getCode()));
+            }
+        }
+    }
+
+    /**
+     * 字符串格式转日期
+     */
+    public static class CustomStringDateConverter implements Converter<String, Date> {
+        private static final String dateFormat = "yyyy-MM-dd HH:mm:ss";
+        private static final String shortDateFormat = "yyyy-MM-dd";
+        private static final String dateFormat2 = "yyyy/MM/dd HH:mm:ss";
+        private static final String shortDateFormat2 = "yyyy/MM/dd";
+
+        @Override
+        public Date convert(String source) {
+            if (org.apache.commons.lang3.StringUtils.isBlank(source)) {
+                return null;
+            }
+            source = source.trim();
+            try {
+                SimpleDateFormat formatter;
+                if (source.contains("-")) {
+                    if (source.contains(":")) {
+                        formatter = new SimpleDateFormat(dateFormat);
+                    } else {
+                        formatter = new SimpleDateFormat(shortDateFormat);
+                    }
+                    return formatter.parse(source);
+                } else if (source.contains("/")) {
+                    if (source.contains(":")) {
+                        formatter = new SimpleDateFormat(dateFormat2);
+                    } else {
+                        formatter = new SimpleDateFormat(shortDateFormat2);
+                    }
+                    return formatter.parse(source);
+                }
+            } catch (Exception e) {
+                throw new RuntimeException(String.format("parser %s to Date fail", source));
+            }
+
+            throw new RuntimeException(String.format("parser %s to Date fail", source));
+        }
+    }
+
+}

+ 58 - 0
cooleshow-bbs/src/main/java/com/yonge/cooleshow/bbs/config/jackson/MappingJSONHttpMessageConverter.java

@@ -0,0 +1,58 @@
+package com.yonge.cooleshow.bbs.config.jackson;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpOutputMessage;
+import org.springframework.http.converter.HttpMessageNotWritableException;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+
+import java.io.IOException;
+import java.lang.reflect.Type;
+
+/**
+ * Created by Eric.Shang on 3/3/17.
+ */
+@Slf4j
+public class MappingJSONHttpMessageConverter extends MappingJackson2HttpMessageConverter {
+
+    public MappingJSONHttpMessageConverter() {
+    }
+
+    public MappingJSONHttpMessageConverter(ObjectMapper objectMapper) {
+        super(objectMapper);
+    }
+
+    /**
+     * 自定义JSON异常封装
+     * @param object Object
+     * @param type Type
+     * @param outputMessage HttpOutputMessage
+     * @throws IOException IOException
+     * @throws HttpMessageNotWritableException HttpMessageNotWritableException
+     */
+    @Override
+    protected void writeInternal(Object object, Type type, HttpOutputMessage outputMessage)
+            throws IOException, HttpMessageNotWritableException {
+
+        /*try {
+
+            if (object instanceof ExtResponse) {
+                // 拓展返回数据结构
+                object = ((ExtResponse<?>) object).data();
+
+            } else if (object instanceof Response) {
+                // 自定义标准数据结构
+                object = SysResponse.from((Response<?>) object);
+
+            } else if (object instanceof JSONResponse) {
+                // 三方标准数据结构,
+                object = JSON.toJSON(object);
+            }
+
+        } catch (Exception e) {
+            object = SysResponse.sysResponse();
+            log.error("jsonObject={}", object, e);
+        }*/
+        super.writeInternal(object, type, outputMessage);
+    }
+}

+ 2 - 6
cooleshow-cms/src/main/java/com/yonge/cooleshow/cms/config/LocalFastJsonHttpMessageConverter.java

@@ -2,12 +2,10 @@ package com.yonge.cooleshow.cms.config;
 
 import com.alibaba.fastjson.serializer.JSONSerializer;
 import com.alibaba.fastjson.serializer.ObjectSerializer;
-import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
 import com.alibaba.fastjson.serializer.ValueFilter;
 import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
 import com.vdurmont.emoji.EmojiParser;
 import com.yonge.toolset.base.enums.BaseEnum;
-import com.yonge.toolset.utils.json.JsonUtil;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.http.HttpInputMessage;
 import org.springframework.http.HttpOutputMessage;
@@ -15,10 +13,8 @@ import org.springframework.http.converter.HttpMessageNotReadableException;
 import org.springframework.http.converter.HttpMessageNotWritableException;
 
 import java.io.IOException;
-import java.io.OutputStream;
 import java.lang.reflect.Type;
 import java.math.BigDecimal;
-import java.util.Date;
 
 public class LocalFastJsonHttpMessageConverter extends FastJsonHttpMessageConverter {
 
@@ -32,12 +28,12 @@ public class LocalFastJsonHttpMessageConverter extends FastJsonHttpMessageConver
 	@Override
 	protected void writeInternal(Object obj, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
 
-		OutputStream out = outputMessage.getBody();
+		/*OutputStream out = outputMessage.getBody();
 		JsonUtil.getConfig().put(Date.class, new SimpleDateFormatSerializer(FORMAT));
 		//JsonUtil.getConfig().put(String.class, new EmojiSerializer());
 		String text = JsonUtil.toJSONString(obj, EnumFilter.instance, getFeatures());
 		byte[] bytes = text.getBytes(getCharset());
-		out.write(bytes);
+		out.write(bytes);*/
 	}
 }
 

+ 57 - 7
cooleshow-cms/src/main/java/com/yonge/cooleshow/cms/config/WebMvcConfig.java

@@ -1,19 +1,25 @@
 package com.yonge.cooleshow.cms.config;
 
-import java.util.ArrayList;
-import java.util.List;
-
+import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
+import com.google.common.collect.Lists;
+import com.yonge.cooleshow.cms.config.jackson.JacksonConfig;
+import com.yonge.cooleshow.cms.config.jackson.MappingJSONHttpMessageConverter;
+import com.yonge.cooleshow.cms.interceptor.OperationLogInterceptor;
+import com.yonge.cooleshow.common.config.EnumConverterFactory;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
-import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
 import org.springframework.format.FormatterRegistry;
 import org.springframework.http.MediaType;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.StringHttpMessageConverter;
 import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 
-import com.yonge.cooleshow.cms.interceptor.OperationLogInterceptor;
-import com.yonge.cooleshow.common.config.EnumConverterFactory;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
 
 @Configuration
 public class WebMvcConfig implements WebMvcConfigurer {
@@ -26,7 +32,10 @@ public class WebMvcConfig implements WebMvcConfigurer {
 	 */
 	@Override
 	public void addFormatters(FormatterRegistry registry) {
+		// 枚举转换器
 		registry.addConverterFactory(new EnumConverterFactory());
+		// 字符串时间转换器
+		registry.addConverter(new JacksonConfig.CustomStringDateConverter());
 	}
 	
 	@Override
@@ -34,7 +43,48 @@ public class WebMvcConfig implements WebMvcConfigurer {
 		registry.addInterceptor(operationLogInterceptor).addPathPatterns("/**").excludePathPatterns("/login");
 	}
 
-	@Bean
+	/**
+	 * @param converters List<HttpMessageConverter<?>>
+	 */
+	@Override
+	public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
+		//WebMvcConfigurer.super.configureMessageConverters(converters);
+
+		// 如果存在fastJson的转换器,将其移除
+		converters.removeIf(httpMessageConverter -> httpMessageConverter instanceof FastJsonHttpMessageConverter);
+
+		// 需要重新加入jackson的转换器,该处的objectMapper已经在配置中注册了
+		MappingJSONHttpMessageConverter converter = new MappingJSONHttpMessageConverter(new JacksonConfig.JacksonObjectMapper());
+		converter.setDefaultCharset(StandardCharsets.UTF_8); // 字符编号
+		converters.add(0, converter);
+
+		// 添加String转换器
+		converters.add(utf8StringHttpMessageConverter());
+	}
+
+	/**
+	 * 自定义String转换器
+	 * @return HttpMessageConverters
+	 */
+	//@Bean
+	@Primary
+	public StringHttpMessageConverter utf8StringHttpMessageConverter() {
+
+		StringHttpMessageConverter converter = new StringHttpMessageConverter();
+
+		List<MediaType> mediaTypes = Lists.newArrayList();
+		mediaTypes.add(MediaType.TEXT_HTML);
+		mediaTypes.add(MediaType.TEXT_PLAIN);
+		mediaTypes.add(MediaType.TEXT_XML);
+		mediaTypes.add(MediaType.APPLICATION_XML);
+
+		converter.setSupportedMediaTypes(mediaTypes);
+		converter.setDefaultCharset(StandardCharsets.UTF_8);
+
+		return converter;
+	}
+
+	//@Bean
     public HttpMessageConverters fastJsonHttpMessageConverters(){
 		LocalFastJsonHttpMessageConverter converter = new LocalFastJsonHttpMessageConverter();
         List<MediaType> fastMediaTypes =  new ArrayList<MediaType>();

+ 302 - 0
cooleshow-cms/src/main/java/com/yonge/cooleshow/cms/config/jackson/JacksonConfig.java

@@ -0,0 +1,302 @@
+package com.yonge.cooleshow.cms.config.jackson;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.BeanProperty;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
+import com.fasterxml.jackson.databind.deser.std.DateDeserializers;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.databind.ser.std.DateSerializer;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
+import com.yonge.cooleshow.common.config.EnumConverterFactory;
+import com.yonge.toolset.base.enums.BaseEnum;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
+import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.util.StringUtils;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.RoundingMode;
+import java.text.DecimalFormat;
+import java.text.SimpleDateFormat;
+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;
+import java.util.TimeZone;
+
+/**
+ * JSON LocalDateTime 序列化、反序列化配置
+ */
+@Configuration
+@ConditionalOnClass(ObjectMapper.class)
+@AutoConfigureBefore(JacksonAutoConfiguration.class)
+public class JacksonConfig {
+
+    public static final String NORM_DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss"; // 时间格式
+    public static final String NORM_DATE_PATTERN = "yyyy-MM-dd";
+    public static final String NORM_TIME_PATTERN = "HH:mm:ss";
+    //public static final String NORM_TIME_ZONE = "GMT+8"; // 时区设置
+    /**
+     * 时区配置
+     */
+    @Bean
+    public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() {
+        return builder -> {
+
+            // 配置Date的格式化
+            builder.locale(Locale.CHINA);
+            builder.timeZone(TimeZone.getTimeZone("Asia/Shanghai"));
+            builder.simpleDateFormat(NORM_DATETIME_PATTERN);
+
+            // 配置Jackson转换配置
+            //builder.configure(new JacksonObjectMapper());
+
+            //builder.serializationInclusion(JsonInclude.Include.USE_DEFAULTS);
+        };
+    }
+
+    /**
+     * 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象
+     * 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]
+     * 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]
+     */
+    public static class JacksonObjectMapper extends ObjectMapper {
+
+        public JacksonObjectMapper() {
+            super();
+            //反序列化的时候如果多了其他属性,不抛出异常
+            this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
+                    //.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true)
+                    //不注释,会导致swagger报错
+                    //.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL)
+                    //关闭日期序列化为时间戳的功能
+                    //.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
+                    //关闭序列化的时候没有为属性找到getter方法,报错
+                    //.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS)
+                    //关闭反序列化的时候,没有找到属性的setter报错
+                    //.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
+                    //序列化的时候序列对象的所有属性
+                    //.setSerializationInclusion(JsonInclude.Include.ALWAYS)
+                    //如果是空对象的时候,不抛异常
+                    //.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
+                    //反序列化时,属性不存在的兼容处理
+                    //.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
+                    .setDateFormat(new SimpleDateFormat(NORM_DATETIME_PATTERN, Locale.SIMPLIFIED_CHINESE))
+                    .setLocale(Locale.CHINA)
+                    .setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
+
+                    SimpleModule simpleModule = new SimpleModule()
+                    // 时间对象反序列化
+                    .addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(NORM_DATETIME_PATTERN)))
+                    .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(NORM_DATE_PATTERN)))
+                    .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(NORM_TIME_PATTERN)))
+                    .addDeserializer(Date.class,new DateDeserializers.DateDeserializer(DateDeserializers.DateDeserializer.instance,
+                            new SimpleDateFormat(NORM_DATETIME_PATTERN), NORM_DATETIME_PATTERN))
+
+                    // 时间对象序列化
+                    .addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(NORM_DATETIME_PATTERN)))
+                    .addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(NORM_DATE_PATTERN)))
+                    .addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(NORM_TIME_PATTERN)))
+                    .addSerializer(Date.class, new DateSerializer(false, new SimpleDateFormat(NORM_DATETIME_PATTERN)))
+
+                     // 枚举类序列化
+                    .addDeserializer(Enum.class, new BaseEnumDeserializer())
+                    .addSerializer(BaseEnum.class, new BaseEnumSerializer())
+
+                    // Long对象转String
+                    //.addSerializer(Float.class, new FloatJsonSerializer())
+                    //.addSerializer(Float.TYPE, new FloatJsonSerializer())
+
+                    .addSerializer(Long.class, ToStringSerializer.instance)
+                    .addSerializer(Long.TYPE, ToStringSerializer.instance)
+
+                    .addSerializer(BigDecimal.class, new BigDecimalJsonSerializer())
+                    .addSerializer(BigInteger.class, ToStringSerializer.instance)
+
+                    .addSerializer(Double.class, new DoubleJsonSerializer())
+                    .addSerializer(Double.TYPE, new DoubleJsonSerializer());
+
+            //注册功能模块 例如,可以添加自定义序列化器和反序列化器
+            this.registerModule(simpleModule);
+        }
+    }
+
+    /**
+     * Double精度处理
+     * #@JsonSerialize(using = JacksonConvertConfig.DoubleJsonSerializer.class)
+     */
+    public static class DoubleJsonSerializer extends JsonSerializer<Double> {
+
+        @Override
+        public void serialize(Double arg0, JsonGenerator arg1, SerializerProvider arg2) throws IOException {
+            if(arg0 != null) {
+                getJsonConvertValue(arg1, new BigDecimal(String.valueOf(arg0)));
+            }
+        }
+    }
+
+    /**
+     * JSON数据转换
+     * @param arg1 JsonGenerator
+     * @param bigDecimal BigDecimal
+     * @throws IOException IOException
+     */
+    private static void getJsonConvertValue(JsonGenerator arg1, BigDecimal bigDecimal) throws IOException {
+
+        // 原本这里是  ##.00 ,带来的问题是如果数据库数据为0.00返回“ .00 “经评论指正,改为0.00
+        DecimalFormat decimalFormat = new DecimalFormat("#.00");
+
+        decimalFormat.setRoundingMode(RoundingMode.HALF_UP);
+        //四舍五入。需要将数据转成bigDecimal, 否则会存在经度丢失问题
+        String format = decimalFormat.format(bigDecimal);
+
+        arg1.writeNumber(new BigDecimal(format));//返回数字格式
+    }
+
+    /**
+     * BigDecimal精度处理
+     * #@JsonSerialize(using = JacksonConvertConfig.BigDecimalJsonSerializer.class)
+     */
+    public static class BigDecimalJsonSerializer extends JsonSerializer<BigDecimal> {
+
+        @Override
+        public void serialize(BigDecimal arg0, JsonGenerator arg1, SerializerProvider arg2) throws IOException {
+            if(arg0 != null) {
+                getJsonConvertValue(arg1, arg0);
+            }
+        }
+    }
+
+    /**
+     * Float精度处理
+     * #@JsonSerialize(using = JacksonConvertConfig.FloatJsonSerializer.class)
+     */
+    public static class FloatJsonSerializer extends JsonSerializer<Float> {
+
+        @Override
+        public void serialize(Float arg0, JsonGenerator arg1, SerializerProvider arg2) throws IOException {
+            if(arg0 != null) {
+                getJsonConvertValue(arg1, new BigDecimal(String.valueOf(arg0)));
+            }
+        }
+    }
+
+    /**
+     * 枚举类反序列化
+     */
+    @Data
+    @EqualsAndHashCode(callSuper = true)
+    public static class BaseEnumDeserializer extends JsonDeserializer<Enum<?>> implements ContextualDeserializer {
+
+        private Class<?> target;
+
+        @SuppressWarnings("all")
+        @Override
+        public Enum<?> deserialize(JsonParser jsonParser, DeserializationContext ctx) throws IOException {
+            if (!StringUtils.hasText(jsonParser.getText())) {
+                return null;
+            }
+
+            if (BaseEnum.class.isAssignableFrom(target)) {
+                return (Enum<?>) EnumConverterFactory.getEnum((Class) target, jsonParser.getText());
+            }
+            return null;
+        }
+
+        /**
+         * @param ctx      DeserializationContext
+         * @param property BeanProperty
+         * @return JsonDeserializer
+         */
+        @Override
+        public JsonDeserializer<?> createContextual(DeserializationContext ctx, BeanProperty property) {
+            Class<?> rawCls = ctx.getContextualType().getRawClass();
+            BaseEnumDeserializer enumDeserializer = new BaseEnumDeserializer();
+            enumDeserializer.setTarget(rawCls);
+            return enumDeserializer;
+        }
+
+    }
+
+    /**
+     * 枚举类序列化
+     */
+    public static class BaseEnumSerializer extends JsonSerializer<BaseEnum> {
+
+        @Override
+        public void serialize(BaseEnum enums, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
+
+            if (enums.getCode() instanceof Integer) {
+                // 返回整形
+                jsonGenerator.writeNumber(Integer.parseInt(String.valueOf(enums.getCode())));
+            } else {
+                // 返回字符串
+                jsonGenerator.writeString(String.valueOf(enums.getCode()));
+            }
+        }
+    }
+
+    /**
+     * 字符串格式转日期
+     */
+    public static class CustomStringDateConverter implements Converter<String, Date> {
+        private static final String dateFormat = "yyyy-MM-dd HH:mm:ss";
+        private static final String shortDateFormat = "yyyy-MM-dd";
+        private static final String dateFormat2 = "yyyy/MM/dd HH:mm:ss";
+        private static final String shortDateFormat2 = "yyyy/MM/dd";
+
+        @Override
+        public Date convert(String source) {
+            if (org.apache.commons.lang3.StringUtils.isBlank(source)) {
+                return null;
+            }
+            source = source.trim();
+            try {
+                SimpleDateFormat formatter;
+                if (source.contains("-")) {
+                    if (source.contains(":")) {
+                        formatter = new SimpleDateFormat(dateFormat);
+                    } else {
+                        formatter = new SimpleDateFormat(shortDateFormat);
+                    }
+                    return formatter.parse(source);
+                } else if (source.contains("/")) {
+                    if (source.contains(":")) {
+                        formatter = new SimpleDateFormat(dateFormat2);
+                    } else {
+                        formatter = new SimpleDateFormat(shortDateFormat2);
+                    }
+                    return formatter.parse(source);
+                }
+            } catch (Exception e) {
+                throw new RuntimeException(String.format("parser %s to Date fail", source));
+            }
+
+            throw new RuntimeException(String.format("parser %s to Date fail", source));
+        }
+    }
+
+}

+ 58 - 0
cooleshow-cms/src/main/java/com/yonge/cooleshow/cms/config/jackson/MappingJSONHttpMessageConverter.java

@@ -0,0 +1,58 @@
+package com.yonge.cooleshow.cms.config.jackson;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpOutputMessage;
+import org.springframework.http.converter.HttpMessageNotWritableException;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+
+import java.io.IOException;
+import java.lang.reflect.Type;
+
+/**
+ * Created by Eric.Shang on 3/3/17.
+ */
+@Slf4j
+public class MappingJSONHttpMessageConverter extends MappingJackson2HttpMessageConverter {
+
+    public MappingJSONHttpMessageConverter() {
+    }
+
+    public MappingJSONHttpMessageConverter(ObjectMapper objectMapper) {
+        super(objectMapper);
+    }
+
+    /**
+     * 自定义JSON异常封装
+     * @param object Object
+     * @param type Type
+     * @param outputMessage HttpOutputMessage
+     * @throws IOException IOException
+     * @throws HttpMessageNotWritableException HttpMessageNotWritableException
+     */
+    @Override
+    protected void writeInternal(Object object, Type type, HttpOutputMessage outputMessage)
+            throws IOException, HttpMessageNotWritableException {
+
+        /*try {
+
+            if (object instanceof ExtResponse) {
+                // 拓展返回数据结构
+                object = ((ExtResponse<?>) object).data();
+
+            } else if (object instanceof Response) {
+                // 自定义标准数据结构
+                object = SysResponse.from((Response<?>) object);
+
+            } else if (object instanceof JSONResponse) {
+                // 三方标准数据结构,
+                object = JSON.toJSON(object);
+            }
+
+        } catch (Exception e) {
+            object = SysResponse.sysResponse();
+            log.error("jsonObject={}", object, e);
+        }*/
+        super.writeInternal(object, type, outputMessage);
+    }
+}

+ 16 - 0
cooleshow-common/src/main/java/com/yonge/cooleshow/common/config/EnumConverterFactory.java

@@ -53,4 +53,20 @@ public class EnumConverterFactory implements ConverterFactory<Object, BaseEnum<?
 		return null;
 	}
 
+	/**
+	 * 根据code获取枚举
+	 * @param targetType 枚举类型
+	 * @param source code
+	 * @return 枚举
+	 * @param <T> 枚举类型
+	 */
+	public static <T extends BaseEnum<?,?>> T getEnum(Class<T> targetType, String source) {
+		for (T constant : targetType.getEnumConstants()) {
+			if (source.equals(String.valueOf(constant.getCode()))) {
+				return constant;
+			}
+		}
+		return null;
+	}
+
 }

+ 2 - 6
cooleshow-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/config/LocalFastJsonHttpMessageConverter.java

@@ -2,12 +2,10 @@ package com.yonge.cooleshow.admin.config;
 
 import com.alibaba.fastjson.serializer.JSONSerializer;
 import com.alibaba.fastjson.serializer.ObjectSerializer;
-import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
 import com.alibaba.fastjson.serializer.ValueFilter;
 import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
 import com.vdurmont.emoji.EmojiParser;
 import com.yonge.toolset.base.enums.BaseEnum;
-import com.yonge.toolset.utils.json.JsonUtil;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.http.HttpInputMessage;
 import org.springframework.http.HttpOutputMessage;
@@ -15,10 +13,8 @@ import org.springframework.http.converter.HttpMessageNotReadableException;
 import org.springframework.http.converter.HttpMessageNotWritableException;
 
 import java.io.IOException;
-import java.io.OutputStream;
 import java.lang.reflect.Type;
 import java.math.BigDecimal;
-import java.util.Date;
 
 public class LocalFastJsonHttpMessageConverter extends FastJsonHttpMessageConverter {
 
@@ -32,12 +28,12 @@ public class LocalFastJsonHttpMessageConverter extends FastJsonHttpMessageConver
 	@Override
 	protected void writeInternal(Object obj, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
 
-		OutputStream out = outputMessage.getBody();
+		/*OutputStream out = outputMessage.getBody();
 		JsonUtil.getConfig().put(Date.class, new SimpleDateFormatSerializer(FORMAT));
 		//JsonUtil.getConfig().put(String.class, new EmojiSerializer());
 		String text = JsonUtil.toJSONString(obj, EnumFilter.instance, getFeatures());
 		byte[] bytes = text.getBytes(getCharset());
-		out.write(bytes);
+		out.write(bytes);*/
 	}
 }
 

+ 53 - 2
cooleshow-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/config/WebMvcConfig.java

@@ -1,14 +1,21 @@
 package com.yonge.cooleshow.admin.config;
 
+import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
+import com.google.common.collect.Lists;
+import com.yonge.cooleshow.admin.config.jackson.JacksonConfig;
+import com.yonge.cooleshow.admin.config.jackson.MappingJSONHttpMessageConverter;
 import com.yonge.cooleshow.common.config.EnumConverterFactory;
 import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
-import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
 import org.springframework.format.FormatterRegistry;
 import org.springframework.http.MediaType;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.StringHttpMessageConverter;
 import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -21,7 +28,10 @@ public class WebMvcConfig implements WebMvcConfigurer {
 	 */
 	@Override
 	public void addFormatters(FormatterRegistry registry) {
+		// 枚举转换器
 		registry.addConverterFactory(new EnumConverterFactory());
+		// 字符串时间转换器
+		registry.addConverter(new JacksonConfig.CustomStringDateConverter());
 	}
 
 	@Override
@@ -39,7 +49,48 @@ public class WebMvcConfig implements WebMvcConfigurer {
 //		registry.addInterceptor(operationLogInterceptor).addPathPatterns("/**").excludePathPatterns("/login");
 	}
 
-	@Bean
+	/**
+	 * @param converters List<HttpMessageConverter<?>>
+	 */
+	@Override
+	public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
+		//WebMvcConfigurer.super.configureMessageConverters(converters);
+
+		// 如果存在fastJson的转换器,将其移除
+		converters.removeIf(httpMessageConverter -> httpMessageConverter instanceof FastJsonHttpMessageConverter);
+
+		// 需要重新加入jackson的转换器,该处的objectMapper已经在配置中注册了
+		MappingJSONHttpMessageConverter converter = new MappingJSONHttpMessageConverter(new JacksonConfig.JacksonObjectMapper());
+		converter.setDefaultCharset(StandardCharsets.UTF_8); // 字符编号
+		converters.add(0, converter);
+
+		// 添加String转换器
+		converters.add(utf8StringHttpMessageConverter());
+	}
+
+	/**
+	 * 自定义String转换器
+	 * @return HttpMessageConverters
+	 */
+	//@Bean
+	@Primary
+	public StringHttpMessageConverter utf8StringHttpMessageConverter() {
+
+		StringHttpMessageConverter converter = new StringHttpMessageConverter();
+
+		List<MediaType> mediaTypes = Lists.newArrayList();
+		mediaTypes.add(MediaType.TEXT_HTML);
+		mediaTypes.add(MediaType.TEXT_PLAIN);
+		mediaTypes.add(MediaType.TEXT_XML);
+		mediaTypes.add(MediaType.APPLICATION_XML);
+
+		converter.setSupportedMediaTypes(mediaTypes);
+		converter.setDefaultCharset(StandardCharsets.UTF_8);
+
+		return converter;
+	}
+
+	//@Bean
 	public HttpMessageConverters fastJsonHttpMessageConverters() {
 		LocalFastJsonHttpMessageConverter converter = new LocalFastJsonHttpMessageConverter();
 		List<MediaType> fastMediaTypes = new ArrayList<MediaType>();

+ 302 - 0
cooleshow-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/config/jackson/JacksonConfig.java

@@ -0,0 +1,302 @@
+package com.yonge.cooleshow.admin.config.jackson;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.BeanProperty;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
+import com.fasterxml.jackson.databind.deser.std.DateDeserializers;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.databind.ser.std.DateSerializer;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
+import com.yonge.cooleshow.common.config.EnumConverterFactory;
+import com.yonge.toolset.base.enums.BaseEnum;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
+import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.util.StringUtils;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.RoundingMode;
+import java.text.DecimalFormat;
+import java.text.SimpleDateFormat;
+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;
+import java.util.TimeZone;
+
+/**
+ * JSON LocalDateTime 序列化、反序列化配置
+ */
+@Configuration
+@ConditionalOnClass(ObjectMapper.class)
+@AutoConfigureBefore(JacksonAutoConfiguration.class)
+public class JacksonConfig {
+
+    public static final String NORM_DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss"; // 时间格式
+    public static final String NORM_DATE_PATTERN = "yyyy-MM-dd";
+    public static final String NORM_TIME_PATTERN = "HH:mm:ss";
+    //public static final String NORM_TIME_ZONE = "GMT+8"; // 时区设置
+    /**
+     * 时区配置
+     */
+    @Bean
+    public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() {
+        return builder -> {
+
+            // 配置Date的格式化
+            builder.locale(Locale.CHINA);
+            builder.timeZone(TimeZone.getTimeZone("Asia/Shanghai"));
+            builder.simpleDateFormat(NORM_DATETIME_PATTERN);
+
+            // 配置Jackson转换配置
+            //builder.configure(new JacksonObjectMapper());
+
+            //builder.serializationInclusion(JsonInclude.Include.USE_DEFAULTS);
+        };
+    }
+
+    /**
+     * 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象
+     * 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]
+     * 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]
+     */
+    public static class JacksonObjectMapper extends ObjectMapper {
+
+        public JacksonObjectMapper() {
+            super();
+            //反序列化的时候如果多了其他属性,不抛出异常
+            this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
+                    //.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true)
+                    //不注释,会导致swagger报错
+                    //.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL)
+                    //关闭日期序列化为时间戳的功能
+                    //.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
+                    //关闭序列化的时候没有为属性找到getter方法,报错
+                    //.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS)
+                    //关闭反序列化的时候,没有找到属性的setter报错
+                    //.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
+                    //序列化的时候序列对象的所有属性
+                    //.setSerializationInclusion(JsonInclude.Include.ALWAYS)
+                    //如果是空对象的时候,不抛异常
+                    //.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
+                    //反序列化时,属性不存在的兼容处理
+                    //.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
+                    .setDateFormat(new SimpleDateFormat(NORM_DATETIME_PATTERN, Locale.SIMPLIFIED_CHINESE))
+                    .setLocale(Locale.CHINA)
+                    .setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
+
+                    SimpleModule simpleModule = new SimpleModule()
+                    // 时间对象反序列化
+                    .addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(NORM_DATETIME_PATTERN)))
+                    .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(NORM_DATE_PATTERN)))
+                    .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(NORM_TIME_PATTERN)))
+                    .addDeserializer(Date.class,new DateDeserializers.DateDeserializer(DateDeserializers.DateDeserializer.instance,
+                            new SimpleDateFormat(NORM_DATETIME_PATTERN), NORM_DATETIME_PATTERN))
+
+                    // 时间对象序列化
+                    .addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(NORM_DATETIME_PATTERN)))
+                    .addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(NORM_DATE_PATTERN)))
+                    .addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(NORM_TIME_PATTERN)))
+                    .addSerializer(Date.class, new DateSerializer(false, new SimpleDateFormat(NORM_DATETIME_PATTERN)))
+
+                     // 枚举类序列化
+                    .addDeserializer(Enum.class, new BaseEnumDeserializer())
+                    .addSerializer(BaseEnum.class, new BaseEnumSerializer())
+
+                    // Long对象转String
+                    //.addSerializer(Float.class, new FloatJsonSerializer())
+                    //.addSerializer(Float.TYPE, new FloatJsonSerializer())
+
+                    .addSerializer(Long.class, ToStringSerializer.instance)
+                    .addSerializer(Long.TYPE, ToStringSerializer.instance)
+
+                    .addSerializer(BigDecimal.class, new BigDecimalJsonSerializer())
+                    .addSerializer(BigInteger.class, ToStringSerializer.instance)
+
+                    .addSerializer(Double.class, new DoubleJsonSerializer())
+                    .addSerializer(Double.TYPE, new DoubleJsonSerializer());
+
+            //注册功能模块 例如,可以添加自定义序列化器和反序列化器
+            this.registerModule(simpleModule);
+        }
+    }
+
+    /**
+     * Double精度处理
+     * #@JsonSerialize(using = JacksonConvertConfig.DoubleJsonSerializer.class)
+     */
+    public static class DoubleJsonSerializer extends JsonSerializer<Double> {
+
+        @Override
+        public void serialize(Double arg0, JsonGenerator arg1, SerializerProvider arg2) throws IOException {
+            if(arg0 != null) {
+                getJsonConvertValue(arg1, new BigDecimal(String.valueOf(arg0)));
+            }
+        }
+    }
+
+    /**
+     * JSON数据转换
+     * @param arg1 JsonGenerator
+     * @param bigDecimal BigDecimal
+     * @throws IOException IOException
+     */
+    private static void getJsonConvertValue(JsonGenerator arg1, BigDecimal bigDecimal) throws IOException {
+
+        // 原本这里是  ##.00 ,带来的问题是如果数据库数据为0.00返回“ .00 “经评论指正,改为0.00
+        DecimalFormat decimalFormat = new DecimalFormat("#.00");
+
+        decimalFormat.setRoundingMode(RoundingMode.HALF_UP);
+        //四舍五入。需要将数据转成bigDecimal, 否则会存在经度丢失问题
+        String format = decimalFormat.format(bigDecimal);
+
+        arg1.writeNumber(new BigDecimal(format));//返回数字格式
+    }
+
+    /**
+     * BigDecimal精度处理
+     * #@JsonSerialize(using = JacksonConvertConfig.BigDecimalJsonSerializer.class)
+     */
+    public static class BigDecimalJsonSerializer extends JsonSerializer<BigDecimal> {
+
+        @Override
+        public void serialize(BigDecimal arg0, JsonGenerator arg1, SerializerProvider arg2) throws IOException {
+            if(arg0 != null) {
+                getJsonConvertValue(arg1, arg0);
+            }
+        }
+    }
+
+    /**
+     * Float精度处理
+     * #@JsonSerialize(using = JacksonConvertConfig.FloatJsonSerializer.class)
+     */
+    public static class FloatJsonSerializer extends JsonSerializer<Float> {
+
+        @Override
+        public void serialize(Float arg0, JsonGenerator arg1, SerializerProvider arg2) throws IOException {
+            if(arg0 != null) {
+                getJsonConvertValue(arg1, new BigDecimal(String.valueOf(arg0)));
+            }
+        }
+    }
+
+    /**
+     * 枚举类反序列化
+     */
+    @Data
+    @EqualsAndHashCode(callSuper = true)
+    public static class BaseEnumDeserializer extends JsonDeserializer<Enum<?>> implements ContextualDeserializer {
+
+        private Class<?> target;
+
+        @SuppressWarnings("all")
+        @Override
+        public Enum<?> deserialize(JsonParser jsonParser, DeserializationContext ctx) throws IOException {
+            if (!StringUtils.hasText(jsonParser.getText())) {
+                return null;
+            }
+
+            if (BaseEnum.class.isAssignableFrom(target)) {
+                return (Enum<?>) EnumConverterFactory.getEnum((Class) target, jsonParser.getText());
+            }
+            return null;
+        }
+
+        /**
+         * @param ctx      DeserializationContext
+         * @param property BeanProperty
+         * @return JsonDeserializer
+         */
+        @Override
+        public JsonDeserializer<?> createContextual(DeserializationContext ctx, BeanProperty property) {
+            Class<?> rawCls = ctx.getContextualType().getRawClass();
+            BaseEnumDeserializer enumDeserializer = new BaseEnumDeserializer();
+            enumDeserializer.setTarget(rawCls);
+            return enumDeserializer;
+        }
+
+    }
+
+    /**
+     * 枚举类序列化
+     */
+    public static class BaseEnumSerializer extends JsonSerializer<BaseEnum> {
+
+        @Override
+        public void serialize(BaseEnum enums, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
+
+            if (enums.getCode() instanceof Integer) {
+                // 返回整形
+                jsonGenerator.writeNumber(Integer.parseInt(String.valueOf(enums.getCode())));
+            } else {
+                // 返回字符串
+                jsonGenerator.writeString(String.valueOf(enums.getCode()));
+            }
+        }
+    }
+
+    /**
+     * 字符串格式转日期
+     */
+    public static class CustomStringDateConverter implements Converter<String, Date> {
+        private static final String dateFormat = "yyyy-MM-dd HH:mm:ss";
+        private static final String shortDateFormat = "yyyy-MM-dd";
+        private static final String dateFormat2 = "yyyy/MM/dd HH:mm:ss";
+        private static final String shortDateFormat2 = "yyyy/MM/dd";
+
+        @Override
+        public Date convert(String source) {
+            if (org.apache.commons.lang3.StringUtils.isBlank(source)) {
+                return null;
+            }
+            source = source.trim();
+            try {
+                SimpleDateFormat formatter;
+                if (source.contains("-")) {
+                    if (source.contains(":")) {
+                        formatter = new SimpleDateFormat(dateFormat);
+                    } else {
+                        formatter = new SimpleDateFormat(shortDateFormat);
+                    }
+                    return formatter.parse(source);
+                } else if (source.contains("/")) {
+                    if (source.contains(":")) {
+                        formatter = new SimpleDateFormat(dateFormat2);
+                    } else {
+                        formatter = new SimpleDateFormat(shortDateFormat2);
+                    }
+                    return formatter.parse(source);
+                }
+            } catch (Exception e) {
+                throw new RuntimeException(String.format("parser %s to Date fail", source));
+            }
+
+            throw new RuntimeException(String.format("parser %s to Date fail", source));
+        }
+    }
+
+}

+ 58 - 0
cooleshow-mall/mall-admin/src/main/java/com/yonge/cooleshow/admin/config/jackson/MappingJSONHttpMessageConverter.java

@@ -0,0 +1,58 @@
+package com.yonge.cooleshow.admin.config.jackson;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpOutputMessage;
+import org.springframework.http.converter.HttpMessageNotWritableException;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+
+import java.io.IOException;
+import java.lang.reflect.Type;
+
+/**
+ * Created by Eric.Shang on 3/3/17.
+ */
+@Slf4j
+public class MappingJSONHttpMessageConverter extends MappingJackson2HttpMessageConverter {
+
+    public MappingJSONHttpMessageConverter() {
+    }
+
+    public MappingJSONHttpMessageConverter(ObjectMapper objectMapper) {
+        super(objectMapper);
+    }
+
+    /**
+     * 自定义JSON异常封装
+     * @param object Object
+     * @param type Type
+     * @param outputMessage HttpOutputMessage
+     * @throws IOException IOException
+     * @throws HttpMessageNotWritableException HttpMessageNotWritableException
+     */
+    @Override
+    protected void writeInternal(Object object, Type type, HttpOutputMessage outputMessage)
+            throws IOException, HttpMessageNotWritableException {
+
+        /*try {
+
+            if (object instanceof ExtResponse) {
+                // 拓展返回数据结构
+                object = ((ExtResponse<?>) object).data();
+
+            } else if (object instanceof Response) {
+                // 自定义标准数据结构
+                object = SysResponse.from((Response<?>) object);
+
+            } else if (object instanceof JSONResponse) {
+                // 三方标准数据结构,
+                object = JSON.toJSON(object);
+            }
+
+        } catch (Exception e) {
+            object = SysResponse.sysResponse();
+            log.error("jsonObject={}", object, e);
+        }*/
+        super.writeInternal(object, type, outputMessage);
+    }
+}

+ 2 - 3
cooleshow-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/config/JacksonConfig.java → cooleshow-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/config/JacksonConfig2.java

@@ -4,7 +4,6 @@ import com.fasterxml.jackson.annotation.JsonInclude;
 import com.fasterxml.jackson.databind.ObjectMapper;
 import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
 import org.springframework.context.annotation.Bean;
-import org.springframework.context.annotation.Configuration;
 import org.springframework.context.annotation.Primary;
 import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
 
@@ -14,8 +13,8 @@ import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
  * 配置json不返回null的字段
  * Created by macro on 2018/8/2.
  */
-@Configuration
-public class JacksonConfig {
+//@Configuration
+public class JacksonConfig2 {
     @Bean
     @Primary
     @ConditionalOnMissingBean(ObjectMapper.class)

+ 2 - 6
cooleshow-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/config/LocalFastJsonHttpMessageConverter.java

@@ -2,12 +2,10 @@ package com.yonge.cooleshow.portal.config;
 
 import com.alibaba.fastjson.serializer.JSONSerializer;
 import com.alibaba.fastjson.serializer.ObjectSerializer;
-import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
 import com.alibaba.fastjson.serializer.ValueFilter;
 import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
 import com.vdurmont.emoji.EmojiParser;
 import com.yonge.toolset.base.enums.BaseEnum;
-import com.yonge.toolset.utils.json.JsonUtil;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.http.HttpInputMessage;
 import org.springframework.http.HttpOutputMessage;
@@ -15,10 +13,8 @@ import org.springframework.http.converter.HttpMessageNotReadableException;
 import org.springframework.http.converter.HttpMessageNotWritableException;
 
 import java.io.IOException;
-import java.io.OutputStream;
 import java.lang.reflect.Type;
 import java.math.BigDecimal;
-import java.util.Date;
 
 public class LocalFastJsonHttpMessageConverter extends FastJsonHttpMessageConverter {
 
@@ -32,12 +28,12 @@ public class LocalFastJsonHttpMessageConverter extends FastJsonHttpMessageConver
 	@Override
 	protected void writeInternal(Object obj, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
 
-		OutputStream out = outputMessage.getBody();
+		/*OutputStream out = outputMessage.getBody();
 		JsonUtil.getConfig().put(Date.class, new SimpleDateFormatSerializer(FORMAT));
 		//JsonUtil.getConfig().put(String.class, new EmojiSerializer());
 		String text = JsonUtil.toJSONString(obj, EnumFilter.instance, getFeatures());
 		byte[] bytes = text.getBytes(getCharset());
-		out.write(bytes);
+		out.write(bytes);*/
 	}
 }
 

+ 53 - 2
cooleshow-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/config/WebMvcConfig.java

@@ -1,16 +1,23 @@
 package com.yonge.cooleshow.portal.config;
 
+import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
+import com.google.common.collect.Lists;
 import com.yonge.cooleshow.common.config.EnumConverterFactory;
+import com.yonge.cooleshow.portal.config.jackson.JacksonConfig;
+import com.yonge.cooleshow.portal.config.jackson.MappingJSONHttpMessageConverter;
 import com.yonge.cooleshow.portal.interceptor.MDCInterceptor;
 import org.springframework.beans.factory.annotation.Autowired;
 import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
-import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
 import org.springframework.format.FormatterRegistry;
 import org.springframework.http.MediaType;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.StringHttpMessageConverter;
 import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 
+import java.nio.charset.StandardCharsets;
 import java.util.ArrayList;
 import java.util.List;
 
@@ -25,7 +32,10 @@ public class WebMvcConfig implements WebMvcConfigurer {
 	 */
 	@Override
 	public void addFormatters(FormatterRegistry registry) {
+		// 枚举转换器
 		registry.addConverterFactory(new EnumConverterFactory());
+		// 字符串时间转换器
+		registry.addConverter(new JacksonConfig.CustomStringDateConverter());
 	}
 
 	@Override
@@ -43,7 +53,48 @@ public class WebMvcConfig implements WebMvcConfigurer {
 //		registry.addInterceptor(operationLogInterceptor).addPathPatterns("/**").excludePathPatterns("/login");
 	}
 
-	@Bean
+	/**
+	 * @param converters List<HttpMessageConverter<?>>
+	 */
+	@Override
+	public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
+		//WebMvcConfigurer.super.configureMessageConverters(converters);
+
+		// 如果存在fastJson的转换器,将其移除
+		converters.removeIf(httpMessageConverter -> httpMessageConverter instanceof FastJsonHttpMessageConverter);
+
+		// 需要重新加入jackson的转换器,该处的objectMapper已经在配置中注册了
+		MappingJSONHttpMessageConverter converter = new MappingJSONHttpMessageConverter(new JacksonConfig.JacksonObjectMapper());
+		converter.setDefaultCharset(StandardCharsets.UTF_8); // 字符编号
+		converters.add(0, converter);
+
+		// 添加String转换器
+		converters.add(utf8StringHttpMessageConverter());
+	}
+
+	/**
+	 * 自定义String转换器
+	 * @return HttpMessageConverters
+	 */
+	//@Bean
+	@Primary
+	public StringHttpMessageConverter utf8StringHttpMessageConverter() {
+
+		StringHttpMessageConverter converter = new StringHttpMessageConverter();
+
+		List<MediaType> mediaTypes = Lists.newArrayList();
+		mediaTypes.add(MediaType.TEXT_HTML);
+		mediaTypes.add(MediaType.TEXT_PLAIN);
+		mediaTypes.add(MediaType.TEXT_XML);
+		mediaTypes.add(MediaType.APPLICATION_XML);
+
+		converter.setSupportedMediaTypes(mediaTypes);
+		converter.setDefaultCharset(StandardCharsets.UTF_8);
+
+		return converter;
+	}
+
+	//@Bean
 	public HttpMessageConverters fastJsonHttpMessageConverters() {
 		LocalFastJsonHttpMessageConverter converter = new LocalFastJsonHttpMessageConverter();
 		List<MediaType> fastMediaTypes = new ArrayList<MediaType>();

+ 302 - 0
cooleshow-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/config/jackson/JacksonConfig.java

@@ -0,0 +1,302 @@
+package com.yonge.cooleshow.portal.config.jackson;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.BeanProperty;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
+import com.fasterxml.jackson.databind.deser.std.DateDeserializers;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.databind.ser.std.DateSerializer;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
+import com.yonge.cooleshow.common.config.EnumConverterFactory;
+import com.yonge.toolset.base.enums.BaseEnum;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
+import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.util.StringUtils;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.RoundingMode;
+import java.text.DecimalFormat;
+import java.text.SimpleDateFormat;
+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;
+import java.util.TimeZone;
+
+/**
+ * JSON LocalDateTime 序列化、反序列化配置
+ */
+@Configuration
+@ConditionalOnClass(ObjectMapper.class)
+@AutoConfigureBefore(JacksonAutoConfiguration.class)
+public class JacksonConfig {
+
+    public static final String NORM_DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss"; // 时间格式
+    public static final String NORM_DATE_PATTERN = "yyyy-MM-dd";
+    public static final String NORM_TIME_PATTERN = "HH:mm:ss";
+    //public static final String NORM_TIME_ZONE = "GMT+8"; // 时区设置
+    /**
+     * 时区配置
+     */
+    @Bean
+    public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() {
+        return builder -> {
+
+            // 配置Date的格式化
+            builder.locale(Locale.CHINA);
+            builder.timeZone(TimeZone.getTimeZone("Asia/Shanghai"));
+            builder.simpleDateFormat(NORM_DATETIME_PATTERN);
+
+            // 配置Jackson转换配置
+            //builder.configure(new JacksonObjectMapper());
+
+            //builder.serializationInclusion(JsonInclude.Include.USE_DEFAULTS);
+        };
+    }
+
+    /**
+     * 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象
+     * 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]
+     * 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]
+     */
+    public static class JacksonObjectMapper extends ObjectMapper {
+
+        public JacksonObjectMapper() {
+            super();
+            //反序列化的时候如果多了其他属性,不抛出异常
+            this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
+                    //.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true)
+                    //不注释,会导致swagger报错
+                    //.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL)
+                    //关闭日期序列化为时间戳的功能
+                    //.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
+                    //关闭序列化的时候没有为属性找到getter方法,报错
+                    //.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS)
+                    //关闭反序列化的时候,没有找到属性的setter报错
+                    //.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
+                    //序列化的时候序列对象的所有属性
+                    //.setSerializationInclusion(JsonInclude.Include.ALWAYS)
+                    //如果是空对象的时候,不抛异常
+                    //.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
+                    //反序列化时,属性不存在的兼容处理
+                    //.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
+                    .setDateFormat(new SimpleDateFormat(NORM_DATETIME_PATTERN, Locale.SIMPLIFIED_CHINESE))
+                    .setLocale(Locale.CHINA)
+                    .setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
+
+                    SimpleModule simpleModule = new SimpleModule()
+                    // 时间对象反序列化
+                    .addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(NORM_DATETIME_PATTERN)))
+                    .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(NORM_DATE_PATTERN)))
+                    .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(NORM_TIME_PATTERN)))
+                    .addDeserializer(Date.class,new DateDeserializers.DateDeserializer(DateDeserializers.DateDeserializer.instance,
+                            new SimpleDateFormat(NORM_DATETIME_PATTERN), NORM_DATETIME_PATTERN))
+
+                    // 时间对象序列化
+                    .addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(NORM_DATETIME_PATTERN)))
+                    .addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(NORM_DATE_PATTERN)))
+                    .addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(NORM_TIME_PATTERN)))
+                    .addSerializer(Date.class, new DateSerializer(false, new SimpleDateFormat(NORM_DATETIME_PATTERN)))
+
+                     // 枚举类序列化
+                    .addDeserializer(Enum.class, new BaseEnumDeserializer())
+                    .addSerializer(BaseEnum.class, new BaseEnumSerializer())
+
+                    // Long对象转String
+                    //.addSerializer(Float.class, new FloatJsonSerializer())
+                    //.addSerializer(Float.TYPE, new FloatJsonSerializer())
+
+                    .addSerializer(Long.class, ToStringSerializer.instance)
+                    .addSerializer(Long.TYPE, ToStringSerializer.instance)
+
+                    .addSerializer(BigDecimal.class, new BigDecimalJsonSerializer())
+                    .addSerializer(BigInteger.class, ToStringSerializer.instance)
+
+                    .addSerializer(Double.class, new DoubleJsonSerializer())
+                    .addSerializer(Double.TYPE, new DoubleJsonSerializer());
+
+            //注册功能模块 例如,可以添加自定义序列化器和反序列化器
+            this.registerModule(simpleModule);
+        }
+    }
+
+    /**
+     * Double精度处理
+     * #@JsonSerialize(using = JacksonConvertConfig.DoubleJsonSerializer.class)
+     */
+    public static class DoubleJsonSerializer extends JsonSerializer<Double> {
+
+        @Override
+        public void serialize(Double arg0, JsonGenerator arg1, SerializerProvider arg2) throws IOException {
+            if(arg0 != null) {
+                getJsonConvertValue(arg1, new BigDecimal(String.valueOf(arg0)));
+            }
+        }
+    }
+
+    /**
+     * JSON数据转换
+     * @param arg1 JsonGenerator
+     * @param bigDecimal BigDecimal
+     * @throws IOException IOException
+     */
+    private static void getJsonConvertValue(JsonGenerator arg1, BigDecimal bigDecimal) throws IOException {
+
+        // 原本这里是  ##.00 ,带来的问题是如果数据库数据为0.00返回“ .00 “经评论指正,改为0.00
+        DecimalFormat decimalFormat = new DecimalFormat("#.00");
+
+        decimalFormat.setRoundingMode(RoundingMode.HALF_UP);
+        //四舍五入。需要将数据转成bigDecimal, 否则会存在经度丢失问题
+        String format = decimalFormat.format(bigDecimal);
+
+        arg1.writeNumber(new BigDecimal(format));//返回数字格式
+    }
+
+    /**
+     * BigDecimal精度处理
+     * #@JsonSerialize(using = JacksonConvertConfig.BigDecimalJsonSerializer.class)
+     */
+    public static class BigDecimalJsonSerializer extends JsonSerializer<BigDecimal> {
+
+        @Override
+        public void serialize(BigDecimal arg0, JsonGenerator arg1, SerializerProvider arg2) throws IOException {
+            if(arg0 != null) {
+                getJsonConvertValue(arg1, arg0);
+            }
+        }
+    }
+
+    /**
+     * Float精度处理
+     * #@JsonSerialize(using = JacksonConvertConfig.FloatJsonSerializer.class)
+     */
+    public static class FloatJsonSerializer extends JsonSerializer<Float> {
+
+        @Override
+        public void serialize(Float arg0, JsonGenerator arg1, SerializerProvider arg2) throws IOException {
+            if(arg0 != null) {
+                getJsonConvertValue(arg1, new BigDecimal(String.valueOf(arg0)));
+            }
+        }
+    }
+
+    /**
+     * 枚举类反序列化
+     */
+    @Data
+    @EqualsAndHashCode(callSuper = true)
+    public static class BaseEnumDeserializer extends JsonDeserializer<Enum<?>> implements ContextualDeserializer {
+
+        private Class<?> target;
+
+        @SuppressWarnings("all")
+        @Override
+        public Enum<?> deserialize(JsonParser jsonParser, DeserializationContext ctx) throws IOException {
+            if (!StringUtils.hasText(jsonParser.getText())) {
+                return null;
+            }
+
+            if (BaseEnum.class.isAssignableFrom(target)) {
+                return (Enum<?>) EnumConverterFactory.getEnum((Class) target, jsonParser.getText());
+            }
+            return null;
+        }
+
+        /**
+         * @param ctx      DeserializationContext
+         * @param property BeanProperty
+         * @return JsonDeserializer
+         */
+        @Override
+        public JsonDeserializer<?> createContextual(DeserializationContext ctx, BeanProperty property) {
+            Class<?> rawCls = ctx.getContextualType().getRawClass();
+            BaseEnumDeserializer enumDeserializer = new BaseEnumDeserializer();
+            enumDeserializer.setTarget(rawCls);
+            return enumDeserializer;
+        }
+
+    }
+
+    /**
+     * 枚举类序列化
+     */
+    public static class BaseEnumSerializer extends JsonSerializer<BaseEnum> {
+
+        @Override
+        public void serialize(BaseEnum enums, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
+
+            if (enums.getCode() instanceof Integer) {
+                // 返回整形
+                jsonGenerator.writeNumber(Integer.parseInt(String.valueOf(enums.getCode())));
+            } else {
+                // 返回字符串
+                jsonGenerator.writeString(String.valueOf(enums.getCode()));
+            }
+        }
+    }
+
+    /**
+     * 字符串格式转日期
+     */
+    public static class CustomStringDateConverter implements Converter<String, Date> {
+        private static final String dateFormat = "yyyy-MM-dd HH:mm:ss";
+        private static final String shortDateFormat = "yyyy-MM-dd";
+        private static final String dateFormat2 = "yyyy/MM/dd HH:mm:ss";
+        private static final String shortDateFormat2 = "yyyy/MM/dd";
+
+        @Override
+        public Date convert(String source) {
+            if (org.apache.commons.lang3.StringUtils.isBlank(source)) {
+                return null;
+            }
+            source = source.trim();
+            try {
+                SimpleDateFormat formatter;
+                if (source.contains("-")) {
+                    if (source.contains(":")) {
+                        formatter = new SimpleDateFormat(dateFormat);
+                    } else {
+                        formatter = new SimpleDateFormat(shortDateFormat);
+                    }
+                    return formatter.parse(source);
+                } else if (source.contains("/")) {
+                    if (source.contains(":")) {
+                        formatter = new SimpleDateFormat(dateFormat2);
+                    } else {
+                        formatter = new SimpleDateFormat(shortDateFormat2);
+                    }
+                    return formatter.parse(source);
+                }
+            } catch (Exception e) {
+                throw new RuntimeException(String.format("parser %s to Date fail", source));
+            }
+
+            throw new RuntimeException(String.format("parser %s to Date fail", source));
+        }
+    }
+
+}

+ 58 - 0
cooleshow-mall/mall-portal/src/main/java/com/yonge/cooleshow/portal/config/jackson/MappingJSONHttpMessageConverter.java

@@ -0,0 +1,58 @@
+package com.yonge.cooleshow.portal.config.jackson;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpOutputMessage;
+import org.springframework.http.converter.HttpMessageNotWritableException;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+
+import java.io.IOException;
+import java.lang.reflect.Type;
+
+/**
+ * Created by Eric.Shang on 3/3/17.
+ */
+@Slf4j
+public class MappingJSONHttpMessageConverter extends MappingJackson2HttpMessageConverter {
+
+    public MappingJSONHttpMessageConverter() {
+    }
+
+    public MappingJSONHttpMessageConverter(ObjectMapper objectMapper) {
+        super(objectMapper);
+    }
+
+    /**
+     * 自定义JSON异常封装
+     * @param object Object
+     * @param type Type
+     * @param outputMessage HttpOutputMessage
+     * @throws IOException IOException
+     * @throws HttpMessageNotWritableException HttpMessageNotWritableException
+     */
+    @Override
+    protected void writeInternal(Object object, Type type, HttpOutputMessage outputMessage)
+            throws IOException, HttpMessageNotWritableException {
+
+        /*try {
+
+            if (object instanceof ExtResponse) {
+                // 拓展返回数据结构
+                object = ((ExtResponse<?>) object).data();
+
+            } else if (object instanceof Response) {
+                // 自定义标准数据结构
+                object = SysResponse.from((Response<?>) object);
+
+            } else if (object instanceof JSONResponse) {
+                // 三方标准数据结构,
+                object = JSON.toJSON(object);
+            }
+
+        } catch (Exception e) {
+            object = SysResponse.sysResponse();
+            log.error("jsonObject={}", object, e);
+        }*/
+        super.writeInternal(object, type, outputMessage);
+    }
+}

+ 2 - 6
cooleshow-task/src/main/java/com/yonge/cooleshow/task/config/LocalFastJsonHttpMessageConverter.java

@@ -1,10 +1,8 @@
 package com.yonge.cooleshow.task.config;
 
-import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
 import com.alibaba.fastjson.serializer.ValueFilter;
 import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
 import com.yonge.toolset.base.enums.BaseEnum;
-import com.yonge.toolset.utils.json.JsonUtil;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.http.HttpInputMessage;
 import org.springframework.http.HttpOutputMessage;
@@ -12,9 +10,7 @@ import org.springframework.http.converter.HttpMessageNotReadableException;
 import org.springframework.http.converter.HttpMessageNotWritableException;
 
 import java.io.IOException;
-import java.io.OutputStream;
 import java.math.BigDecimal;
-import java.util.Date;
 
 public class LocalFastJsonHttpMessageConverter extends FastJsonHttpMessageConverter {
 
@@ -28,12 +24,12 @@ public class LocalFastJsonHttpMessageConverter extends FastJsonHttpMessageConver
 	@Override
 	protected void writeInternal(Object obj, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
 
-		OutputStream out = outputMessage.getBody();
+		/*OutputStream out = outputMessage.getBody();
 		JsonUtil.getConfig().put(Date.class, new SimpleDateFormatSerializer(FORMAT));
 		//JsonUtil.getConfig().put(String.class, new EmojiSerializer());
 		String text = JsonUtil.toJSONString(obj, EnumFilter.instance, getFeatures());
 		byte[] bytes = text.getBytes(getCharset());
-		out.write(bytes);
+		out.write(bytes);*/
 	}
 }
 

+ 57 - 7
cooleshow-task/src/main/java/com/yonge/cooleshow/task/config/WebMvcConfig.java

@@ -1,16 +1,22 @@
 package com.yonge.cooleshow.task.config;
 
-import java.util.ArrayList;
-import java.util.List;
-
+import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
+import com.google.common.collect.Lists;
+import com.yonge.cooleshow.common.config.EnumConverterFactory;
+import com.yonge.cooleshow.task.config.jackson.JacksonConfig;
+import com.yonge.cooleshow.task.config.jackson.MappingJSONHttpMessageConverter;
 import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
-import org.springframework.context.annotation.Bean;
 import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.Primary;
 import org.springframework.format.FormatterRegistry;
 import org.springframework.http.MediaType;
+import org.springframework.http.converter.HttpMessageConverter;
+import org.springframework.http.converter.StringHttpMessageConverter;
 import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
 
-import com.yonge.cooleshow.common.config.EnumConverterFactory;
+import java.nio.charset.StandardCharsets;
+import java.util.ArrayList;
+import java.util.List;
 
 @Configuration
 public class WebMvcConfig implements WebMvcConfigurer {
@@ -20,10 +26,54 @@ public class WebMvcConfig implements WebMvcConfigurer {
 	 */
 	@Override
 	public void addFormatters(FormatterRegistry registry) {
+		// 枚举转换器
 		registry.addConverterFactory(new EnumConverterFactory());
+		// 字符串时间转换器
+		registry.addConverter(new JacksonConfig.CustomStringDateConverter());
+	}
+
+	/**
+	 * @param converters List<HttpMessageConverter<?>>
+	 */
+	@Override
+	public void configureMessageConverters(List<HttpMessageConverter<?>> converters) {
+		//WebMvcConfigurer.super.configureMessageConverters(converters);
+
+		// 如果存在fastJson的转换器,将其移除
+		converters.removeIf(httpMessageConverter -> httpMessageConverter instanceof FastJsonHttpMessageConverter);
+
+		// 需要重新加入jackson的转换器,该处的objectMapper已经在配置中注册了
+		MappingJSONHttpMessageConverter converter = new MappingJSONHttpMessageConverter(new JacksonConfig.JacksonObjectMapper());
+		converter.setDefaultCharset(StandardCharsets.UTF_8); // 字符编号
+		converters.add(0, converter);
+
+		// 添加String转换器
+		converters.add(utf8StringHttpMessageConverter());
+	}
+
+	/**
+	 * 自定义String转换器
+	 * @return HttpMessageConverters
+	 */
+	//@Bean
+	@Primary
+	public StringHttpMessageConverter utf8StringHttpMessageConverter() {
+
+		StringHttpMessageConverter converter = new StringHttpMessageConverter();
+
+		List<MediaType> mediaTypes = Lists.newArrayList();
+		mediaTypes.add(MediaType.TEXT_HTML);
+		mediaTypes.add(MediaType.TEXT_PLAIN);
+		mediaTypes.add(MediaType.TEXT_XML);
+		mediaTypes.add(MediaType.APPLICATION_XML);
+
+		converter.setSupportedMediaTypes(mediaTypes);
+		converter.setDefaultCharset(StandardCharsets.UTF_8);
+
+		return converter;
 	}
-	
-	@Bean
+
+	//@Bean
     public HttpMessageConverters fastJsonHttpMessageConverters(){
 		LocalFastJsonHttpMessageConverter converter = new LocalFastJsonHttpMessageConverter();
         List<MediaType> fastMediaTypes =  new ArrayList<MediaType>();

+ 302 - 0
cooleshow-task/src/main/java/com/yonge/cooleshow/task/config/jackson/JacksonConfig.java

@@ -0,0 +1,302 @@
+package com.yonge.cooleshow.task.config.jackson;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.BeanProperty;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
+import com.fasterxml.jackson.databind.deser.std.DateDeserializers;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.databind.ser.std.DateSerializer;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
+import com.yonge.cooleshow.common.config.EnumConverterFactory;
+import com.yonge.toolset.base.enums.BaseEnum;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
+import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.util.StringUtils;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.RoundingMode;
+import java.text.DecimalFormat;
+import java.text.SimpleDateFormat;
+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;
+import java.util.TimeZone;
+
+/**
+ * JSON LocalDateTime 序列化、反序列化配置
+ */
+@Configuration
+@ConditionalOnClass(ObjectMapper.class)
+@AutoConfigureBefore(JacksonAutoConfiguration.class)
+public class JacksonConfig {
+
+    public static final String NORM_DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss"; // 时间格式
+    public static final String NORM_DATE_PATTERN = "yyyy-MM-dd";
+    public static final String NORM_TIME_PATTERN = "HH:mm:ss";
+    //public static final String NORM_TIME_ZONE = "GMT+8"; // 时区设置
+    /**
+     * 时区配置
+     */
+    @Bean
+    public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() {
+        return builder -> {
+
+            // 配置Date的格式化
+            builder.locale(Locale.CHINA);
+            builder.timeZone(TimeZone.getTimeZone("Asia/Shanghai"));
+            builder.simpleDateFormat(NORM_DATETIME_PATTERN);
+
+            // 配置Jackson转换配置
+            //builder.configure(new JacksonObjectMapper());
+
+            //builder.serializationInclusion(JsonInclude.Include.USE_DEFAULTS);
+        };
+    }
+
+    /**
+     * 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象
+     * 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]
+     * 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]
+     */
+    public static class JacksonObjectMapper extends ObjectMapper {
+
+        public JacksonObjectMapper() {
+            super();
+            //反序列化的时候如果多了其他属性,不抛出异常
+            this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
+                    //.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true)
+                    //不注释,会导致swagger报错
+                    //.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL)
+                    //关闭日期序列化为时间戳的功能
+                    //.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
+                    //关闭序列化的时候没有为属性找到getter方法,报错
+                    //.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS)
+                    //关闭反序列化的时候,没有找到属性的setter报错
+                    //.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
+                    //序列化的时候序列对象的所有属性
+                    //.setSerializationInclusion(JsonInclude.Include.ALWAYS)
+                    //如果是空对象的时候,不抛异常
+                    //.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
+                    //反序列化时,属性不存在的兼容处理
+                    //.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
+                    .setDateFormat(new SimpleDateFormat(NORM_DATETIME_PATTERN, Locale.SIMPLIFIED_CHINESE))
+                    .setLocale(Locale.CHINA)
+                    .setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
+
+                    SimpleModule simpleModule = new SimpleModule()
+                    // 时间对象反序列化
+                    .addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(NORM_DATETIME_PATTERN)))
+                    .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(NORM_DATE_PATTERN)))
+                    .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(NORM_TIME_PATTERN)))
+                    .addDeserializer(Date.class,new DateDeserializers.DateDeserializer(DateDeserializers.DateDeserializer.instance,
+                            new SimpleDateFormat(NORM_DATETIME_PATTERN), NORM_DATETIME_PATTERN))
+
+                    // 时间对象序列化
+                    .addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(NORM_DATETIME_PATTERN)))
+                    .addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(NORM_DATE_PATTERN)))
+                    .addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(NORM_TIME_PATTERN)))
+                    .addSerializer(Date.class, new DateSerializer(false, new SimpleDateFormat(NORM_DATETIME_PATTERN)))
+
+                     // 枚举类序列化
+                    .addDeserializer(Enum.class, new BaseEnumDeserializer())
+                    .addSerializer(BaseEnum.class, new BaseEnumSerializer())
+
+                    // Long对象转String
+                    //.addSerializer(Float.class, new FloatJsonSerializer())
+                    //.addSerializer(Float.TYPE, new FloatJsonSerializer())
+
+                    .addSerializer(Long.class, ToStringSerializer.instance)
+                    .addSerializer(Long.TYPE, ToStringSerializer.instance)
+
+                    .addSerializer(BigDecimal.class, new BigDecimalJsonSerializer())
+                    .addSerializer(BigInteger.class, ToStringSerializer.instance)
+
+                    .addSerializer(Double.class, new DoubleJsonSerializer())
+                    .addSerializer(Double.TYPE, new DoubleJsonSerializer());
+
+            //注册功能模块 例如,可以添加自定义序列化器和反序列化器
+            this.registerModule(simpleModule);
+        }
+    }
+
+    /**
+     * Double精度处理
+     * #@JsonSerialize(using = JacksonConvertConfig.DoubleJsonSerializer.class)
+     */
+    public static class DoubleJsonSerializer extends JsonSerializer<Double> {
+
+        @Override
+        public void serialize(Double arg0, JsonGenerator arg1, SerializerProvider arg2) throws IOException {
+            if(arg0 != null) {
+                getJsonConvertValue(arg1, new BigDecimal(String.valueOf(arg0)));
+            }
+        }
+    }
+
+    /**
+     * JSON数据转换
+     * @param arg1 JsonGenerator
+     * @param bigDecimal BigDecimal
+     * @throws IOException IOException
+     */
+    private static void getJsonConvertValue(JsonGenerator arg1, BigDecimal bigDecimal) throws IOException {
+
+        // 原本这里是  ##.00 ,带来的问题是如果数据库数据为0.00返回“ .00 “经评论指正,改为0.00
+        DecimalFormat decimalFormat = new DecimalFormat("#.00");
+
+        decimalFormat.setRoundingMode(RoundingMode.HALF_UP);
+        //四舍五入。需要将数据转成bigDecimal, 否则会存在经度丢失问题
+        String format = decimalFormat.format(bigDecimal);
+
+        arg1.writeNumber(new BigDecimal(format));//返回数字格式
+    }
+
+    /**
+     * BigDecimal精度处理
+     * #@JsonSerialize(using = JacksonConvertConfig.BigDecimalJsonSerializer.class)
+     */
+    public static class BigDecimalJsonSerializer extends JsonSerializer<BigDecimal> {
+
+        @Override
+        public void serialize(BigDecimal arg0, JsonGenerator arg1, SerializerProvider arg2) throws IOException {
+            if(arg0 != null) {
+                getJsonConvertValue(arg1, arg0);
+            }
+        }
+    }
+
+    /**
+     * Float精度处理
+     * #@JsonSerialize(using = JacksonConvertConfig.FloatJsonSerializer.class)
+     */
+    public static class FloatJsonSerializer extends JsonSerializer<Float> {
+
+        @Override
+        public void serialize(Float arg0, JsonGenerator arg1, SerializerProvider arg2) throws IOException {
+            if(arg0 != null) {
+                getJsonConvertValue(arg1, new BigDecimal(String.valueOf(arg0)));
+            }
+        }
+    }
+
+    /**
+     * 枚举类反序列化
+     */
+    @Data
+    @EqualsAndHashCode(callSuper = true)
+    public static class BaseEnumDeserializer extends JsonDeserializer<Enum<?>> implements ContextualDeserializer {
+
+        private Class<?> target;
+
+        @SuppressWarnings("all")
+        @Override
+        public Enum<?> deserialize(JsonParser jsonParser, DeserializationContext ctx) throws IOException {
+            if (!StringUtils.hasText(jsonParser.getText())) {
+                return null;
+            }
+
+            if (BaseEnum.class.isAssignableFrom(target)) {
+                return (Enum<?>) EnumConverterFactory.getEnum((Class) target, jsonParser.getText());
+            }
+            return null;
+        }
+
+        /**
+         * @param ctx      DeserializationContext
+         * @param property BeanProperty
+         * @return JsonDeserializer
+         */
+        @Override
+        public JsonDeserializer<?> createContextual(DeserializationContext ctx, BeanProperty property) {
+            Class<?> rawCls = ctx.getContextualType().getRawClass();
+            BaseEnumDeserializer enumDeserializer = new BaseEnumDeserializer();
+            enumDeserializer.setTarget(rawCls);
+            return enumDeserializer;
+        }
+
+    }
+
+    /**
+     * 枚举类序列化
+     */
+    public static class BaseEnumSerializer extends JsonSerializer<BaseEnum> {
+
+        @Override
+        public void serialize(BaseEnum enums, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
+
+            if (enums.getCode() instanceof Integer) {
+                // 返回整形
+                jsonGenerator.writeNumber(Integer.parseInt(String.valueOf(enums.getCode())));
+            } else {
+                // 返回字符串
+                jsonGenerator.writeString(String.valueOf(enums.getCode()));
+            }
+        }
+    }
+
+    /**
+     * 字符串格式转日期
+     */
+    public static class CustomStringDateConverter implements Converter<String, Date> {
+        private static final String dateFormat = "yyyy-MM-dd HH:mm:ss";
+        private static final String shortDateFormat = "yyyy-MM-dd";
+        private static final String dateFormat2 = "yyyy/MM/dd HH:mm:ss";
+        private static final String shortDateFormat2 = "yyyy/MM/dd";
+
+        @Override
+        public Date convert(String source) {
+            if (org.apache.commons.lang3.StringUtils.isBlank(source)) {
+                return null;
+            }
+            source = source.trim();
+            try {
+                SimpleDateFormat formatter;
+                if (source.contains("-")) {
+                    if (source.contains(":")) {
+                        formatter = new SimpleDateFormat(dateFormat);
+                    } else {
+                        formatter = new SimpleDateFormat(shortDateFormat);
+                    }
+                    return formatter.parse(source);
+                } else if (source.contains("/")) {
+                    if (source.contains(":")) {
+                        formatter = new SimpleDateFormat(dateFormat2);
+                    } else {
+                        formatter = new SimpleDateFormat(shortDateFormat2);
+                    }
+                    return formatter.parse(source);
+                }
+            } catch (Exception e) {
+                throw new RuntimeException(String.format("parser %s to Date fail", source));
+            }
+
+            throw new RuntimeException(String.format("parser %s to Date fail", source));
+        }
+    }
+
+}

+ 58 - 0
cooleshow-task/src/main/java/com/yonge/cooleshow/task/config/jackson/MappingJSONHttpMessageConverter.java

@@ -0,0 +1,58 @@
+package com.yonge.cooleshow.task.config.jackson;
+
+import com.fasterxml.jackson.databind.ObjectMapper;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpOutputMessage;
+import org.springframework.http.converter.HttpMessageNotWritableException;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+
+import java.io.IOException;
+import java.lang.reflect.Type;
+
+/**
+ * Created by Eric.Shang on 3/3/17.
+ */
+@Slf4j
+public class MappingJSONHttpMessageConverter extends MappingJackson2HttpMessageConverter {
+
+    public MappingJSONHttpMessageConverter() {
+    }
+
+    public MappingJSONHttpMessageConverter(ObjectMapper objectMapper) {
+        super(objectMapper);
+    }
+
+    /**
+     * 自定义JSON异常封装
+     * @param object Object
+     * @param type Type
+     * @param outputMessage HttpOutputMessage
+     * @throws IOException IOException
+     * @throws HttpMessageNotWritableException HttpMessageNotWritableException
+     */
+    @Override
+    protected void writeInternal(Object object, Type type, HttpOutputMessage outputMessage)
+            throws IOException, HttpMessageNotWritableException {
+
+        /*try {
+
+            if (object instanceof ExtResponse) {
+                // 拓展返回数据结构
+                object = ((ExtResponse<?>) object).data();
+
+            } else if (object instanceof Response) {
+                // 自定义标准数据结构
+                object = SysResponse.from((Response<?>) object);
+
+            } else if (object instanceof JSONResponse) {
+                // 三方标准数据结构,
+                object = JSON.toJSON(object);
+            }
+
+        } catch (Exception e) {
+            object = SysResponse.sysResponse();
+            log.error("jsonObject={}", object, e);
+        }*/
+        super.writeInternal(object, type, outputMessage);
+    }
+}

+ 1 - 1
cooleshow-user/user-biz/pom.xml

@@ -35,7 +35,7 @@
         <dependency>
             <groupId>com.alibaba</groupId>
             <artifactId>fastjson</artifactId>
-            <version>1.2.79</version>
+            <version>2.0.9</version>
         </dependency>
 
         <dependency>

+ 2 - 6
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/config/LocalFastJsonHttpMessageConverter.java

@@ -2,12 +2,10 @@ package com.yonge.cooleshow.biz.dal.config;
 
 import com.alibaba.fastjson.serializer.JSONSerializer;
 import com.alibaba.fastjson.serializer.ObjectSerializer;
-import com.alibaba.fastjson.serializer.SimpleDateFormatSerializer;
 import com.alibaba.fastjson.serializer.ValueFilter;
 import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;
 import com.vdurmont.emoji.EmojiParser;
 import com.yonge.toolset.base.enums.BaseEnum;
-import com.yonge.toolset.utils.json.JsonUtil;
 import org.apache.commons.lang3.StringUtils;
 import org.springframework.http.HttpInputMessage;
 import org.springframework.http.HttpOutputMessage;
@@ -15,10 +13,8 @@ import org.springframework.http.converter.HttpMessageNotReadableException;
 import org.springframework.http.converter.HttpMessageNotWritableException;
 
 import java.io.IOException;
-import java.io.OutputStream;
 import java.lang.reflect.Type;
 import java.math.BigDecimal;
-import java.util.Date;
 
 public class LocalFastJsonHttpMessageConverter extends FastJsonHttpMessageConverter {
 
@@ -32,12 +28,12 @@ public class LocalFastJsonHttpMessageConverter extends FastJsonHttpMessageConver
 	@Override
 	protected void writeInternal(Object obj, HttpOutputMessage outputMessage) throws IOException, HttpMessageNotWritableException {
 
-		OutputStream out = outputMessage.getBody();
+		/*OutputStream out = outputMessage.getBody();
 		JsonUtil.getConfig().put(Date.class, new SimpleDateFormatSerializer(FORMAT));
 		//JsonUtil.getConfig().put(String.class, new EmojiSerializer());
 		String text = JsonUtil.toJSONString(obj, EnumFilter.instance, getFeatures());
 		byte[] bytes = text.getBytes(getCharset());
-		out.write(bytes);
+		out.write(bytes);*/
 	}
 }
 

+ 302 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/config/jackson/JacksonConfig.java

@@ -0,0 +1,302 @@
+package com.yonge.cooleshow.biz.dal.config.jackson;
+
+import com.fasterxml.jackson.core.JsonGenerator;
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.databind.BeanProperty;
+import com.fasterxml.jackson.databind.DeserializationContext;
+import com.fasterxml.jackson.databind.DeserializationFeature;
+import com.fasterxml.jackson.databind.JsonDeserializer;
+import com.fasterxml.jackson.databind.JsonSerializer;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.fasterxml.jackson.databind.SerializerProvider;
+import com.fasterxml.jackson.databind.deser.ContextualDeserializer;
+import com.fasterxml.jackson.databind.deser.std.DateDeserializers;
+import com.fasterxml.jackson.databind.module.SimpleModule;
+import com.fasterxml.jackson.databind.ser.std.DateSerializer;
+import com.fasterxml.jackson.databind.ser.std.ToStringSerializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalDateTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.deser.LocalTimeDeserializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalDateTimeSerializer;
+import com.fasterxml.jackson.datatype.jsr310.ser.LocalTimeSerializer;
+import com.yonge.cooleshow.common.config.EnumConverterFactory;
+import com.yonge.toolset.base.enums.BaseEnum;
+import lombok.Data;
+import lombok.EqualsAndHashCode;
+import org.springframework.boot.autoconfigure.AutoConfigureBefore;
+import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
+import org.springframework.boot.autoconfigure.jackson.Jackson2ObjectMapperBuilderCustomizer;
+import org.springframework.boot.autoconfigure.jackson.JacksonAutoConfiguration;
+import org.springframework.context.annotation.Bean;
+import org.springframework.context.annotation.Configuration;
+import org.springframework.core.convert.converter.Converter;
+import org.springframework.util.StringUtils;
+
+import java.io.IOException;
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.math.RoundingMode;
+import java.text.DecimalFormat;
+import java.text.SimpleDateFormat;
+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;
+import java.util.TimeZone;
+
+/**
+ * JSON LocalDateTime 序列化、反序列化配置
+ */
+@Configuration
+@ConditionalOnClass(ObjectMapper.class)
+@AutoConfigureBefore(JacksonAutoConfiguration.class)
+public class JacksonConfig {
+
+    public static final String NORM_DATETIME_PATTERN = "yyyy-MM-dd HH:mm:ss"; // 时间格式
+    public static final String NORM_DATE_PATTERN = "yyyy-MM-dd";
+    public static final String NORM_TIME_PATTERN = "HH:mm:ss";
+    //public static final String NORM_TIME_ZONE = "GMT+8"; // 时区设置
+    /**
+     * 时区配置
+     */
+    @Bean
+    public Jackson2ObjectMapperBuilderCustomizer jacksonObjectMapperCustomization() {
+        return builder -> {
+
+            // 配置Date的格式化
+            builder.locale(Locale.CHINA);
+            builder.timeZone(TimeZone.getTimeZone("Asia/Shanghai"));
+            builder.simpleDateFormat(NORM_DATETIME_PATTERN);
+
+            // 配置Jackson转换配置
+            //builder.configure(new JacksonObjectMapper());
+
+            //builder.serializationInclusion(JsonInclude.Include.USE_DEFAULTS);
+        };
+    }
+
+    /**
+     * 对象映射器:基于jackson将Java对象转为json,或者将json转为Java对象
+     * 将JSON解析为Java对象的过程称为 [从JSON反序列化Java对象]
+     * 从Java对象生成JSON的过程称为 [序列化Java对象到JSON]
+     */
+    public static class JacksonObjectMapper extends ObjectMapper {
+
+        public JacksonObjectMapper() {
+            super();
+            //反序列化的时候如果多了其他属性,不抛出异常
+            this.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false)
+                    //.configure(DeserializationFeature.USE_BIG_DECIMAL_FOR_FLOATS, true)
+                    //不注释,会导致swagger报错
+                    //.enableDefaultTyping(ObjectMapper.DefaultTyping.NON_FINAL)
+                    //关闭日期序列化为时间戳的功能
+                    //.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS)
+                    //关闭序列化的时候没有为属性找到getter方法,报错
+                    //.disable(SerializationFeature.FAIL_ON_EMPTY_BEANS)
+                    //关闭反序列化的时候,没有找到属性的setter报错
+                    //.disable(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
+                    //序列化的时候序列对象的所有属性
+                    //.setSerializationInclusion(JsonInclude.Include.ALWAYS)
+                    //如果是空对象的时候,不抛异常
+                    //.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false)
+                    //反序列化时,属性不存在的兼容处理
+                    //.getDeserializationConfig().withoutFeatures(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES)
+                    .setDateFormat(new SimpleDateFormat(NORM_DATETIME_PATTERN, Locale.SIMPLIFIED_CHINESE))
+                    .setLocale(Locale.CHINA)
+                    .setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
+
+                    SimpleModule simpleModule = new SimpleModule()
+                    // 时间对象反序列化
+                    .addDeserializer(LocalDateTime.class, new LocalDateTimeDeserializer(DateTimeFormatter.ofPattern(NORM_DATETIME_PATTERN)))
+                    .addDeserializer(LocalDate.class, new LocalDateDeserializer(DateTimeFormatter.ofPattern(NORM_DATE_PATTERN)))
+                    .addDeserializer(LocalTime.class, new LocalTimeDeserializer(DateTimeFormatter.ofPattern(NORM_TIME_PATTERN)))
+                    .addDeserializer(Date.class,new DateDeserializers.DateDeserializer(DateDeserializers.DateDeserializer.instance,
+                            new SimpleDateFormat(NORM_DATETIME_PATTERN), NORM_DATETIME_PATTERN))
+
+                    // 时间对象序列化
+                    .addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DateTimeFormatter.ofPattern(NORM_DATETIME_PATTERN)))
+                    .addSerializer(LocalDate.class, new LocalDateSerializer(DateTimeFormatter.ofPattern(NORM_DATE_PATTERN)))
+                    .addSerializer(LocalTime.class, new LocalTimeSerializer(DateTimeFormatter.ofPattern(NORM_TIME_PATTERN)))
+                    .addSerializer(Date.class, new DateSerializer(false, new SimpleDateFormat(NORM_DATETIME_PATTERN)))
+
+                     // 枚举类序列化
+                    .addDeserializer(Enum.class, new BaseEnumDeserializer())
+                    .addSerializer(BaseEnum.class, new BaseEnumSerializer())
+
+                    // Long对象转String
+                    //.addSerializer(Float.class, new FloatJsonSerializer())
+                    //.addSerializer(Float.TYPE, new FloatJsonSerializer())
+
+                    .addSerializer(Long.class, ToStringSerializer.instance)
+                    .addSerializer(Long.TYPE, ToStringSerializer.instance)
+
+                    .addSerializer(BigDecimal.class, new BigDecimalJsonSerializer())
+                    .addSerializer(BigInteger.class, ToStringSerializer.instance)
+
+                    .addSerializer(Double.class, new DoubleJsonSerializer())
+                    .addSerializer(Double.TYPE, new DoubleJsonSerializer());
+
+            //注册功能模块 例如,可以添加自定义序列化器和反序列化器
+            this.registerModule(simpleModule);
+        }
+    }
+
+    /**
+     * Double精度处理
+     * #@JsonSerialize(using = JacksonConvertConfig.DoubleJsonSerializer.class)
+     */
+    public static class DoubleJsonSerializer extends JsonSerializer<Double> {
+
+        @Override
+        public void serialize(Double arg0, JsonGenerator arg1, SerializerProvider arg2) throws IOException {
+            if(arg0 != null) {
+                getJsonConvertValue(arg1, new BigDecimal(String.valueOf(arg0)));
+            }
+        }
+    }
+
+    /**
+     * JSON数据转换
+     * @param arg1 JsonGenerator
+     * @param bigDecimal BigDecimal
+     * @throws IOException IOException
+     */
+    private static void getJsonConvertValue(JsonGenerator arg1, BigDecimal bigDecimal) throws IOException {
+
+        // 原本这里是  ##.00 ,带来的问题是如果数据库数据为0.00返回“ .00 “经评论指正,改为0.00
+        DecimalFormat decimalFormat = new DecimalFormat("#.00");
+
+        decimalFormat.setRoundingMode(RoundingMode.HALF_UP);
+        //四舍五入。需要将数据转成bigDecimal, 否则会存在经度丢失问题
+        String format = decimalFormat.format(bigDecimal);
+
+        arg1.writeNumber(new BigDecimal(format));//返回数字格式
+    }
+
+    /**
+     * BigDecimal精度处理
+     * #@JsonSerialize(using = JacksonConvertConfig.BigDecimalJsonSerializer.class)
+     */
+    public static class BigDecimalJsonSerializer extends JsonSerializer<BigDecimal> {
+
+        @Override
+        public void serialize(BigDecimal arg0, JsonGenerator arg1, SerializerProvider arg2) throws IOException {
+            if(arg0 != null) {
+                getJsonConvertValue(arg1, arg0);
+            }
+        }
+    }
+
+    /**
+     * Float精度处理
+     * #@JsonSerialize(using = JacksonConvertConfig.FloatJsonSerializer.class)
+     */
+    public static class FloatJsonSerializer extends JsonSerializer<Float> {
+
+        @Override
+        public void serialize(Float arg0, JsonGenerator arg1, SerializerProvider arg2) throws IOException {
+            if(arg0 != null) {
+                getJsonConvertValue(arg1, new BigDecimal(String.valueOf(arg0)));
+            }
+        }
+    }
+
+    /**
+     * 枚举类反序列化
+     */
+    @Data
+    @EqualsAndHashCode(callSuper = true)
+    public static class BaseEnumDeserializer extends JsonDeserializer<Enum<?>> implements ContextualDeserializer {
+
+        private Class<?> target;
+
+        @SuppressWarnings("all")
+        @Override
+        public Enum<?> deserialize(JsonParser jsonParser, DeserializationContext ctx) throws IOException {
+            if (!StringUtils.hasText(jsonParser.getText())) {
+                return null;
+            }
+
+            if (BaseEnum.class.isAssignableFrom(target)) {
+                return (Enum<?>) EnumConverterFactory.getEnum((Class) target, jsonParser.getText());
+            }
+            return null;
+        }
+
+        /**
+         * @param ctx      DeserializationContext
+         * @param property BeanProperty
+         * @return JsonDeserializer
+         */
+        @Override
+        public JsonDeserializer<?> createContextual(DeserializationContext ctx, BeanProperty property) {
+            Class<?> rawCls = ctx.getContextualType().getRawClass();
+            BaseEnumDeserializer enumDeserializer = new BaseEnumDeserializer();
+            enumDeserializer.setTarget(rawCls);
+            return enumDeserializer;
+        }
+
+    }
+
+    /**
+     * 枚举类序列化
+     */
+    public static class BaseEnumSerializer extends JsonSerializer<BaseEnum> {
+
+        @Override
+        public void serialize(BaseEnum enums, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException {
+
+            if (enums.getCode() instanceof Integer) {
+                // 返回整形
+                jsonGenerator.writeNumber(Integer.parseInt(String.valueOf(enums.getCode())));
+            } else {
+                // 返回字符串
+                jsonGenerator.writeString(String.valueOf(enums.getCode()));
+            }
+        }
+    }
+
+    /**
+     * 字符串格式转日期
+     */
+    public static class CustomStringDateConverter implements Converter<String, Date> {
+        private static final String dateFormat = "yyyy-MM-dd HH:mm:ss";
+        private static final String shortDateFormat = "yyyy-MM-dd";
+        private static final String dateFormat2 = "yyyy/MM/dd HH:mm:ss";
+        private static final String shortDateFormat2 = "yyyy/MM/dd";
+
+        @Override
+        public Date convert(String source) {
+            if (org.apache.commons.lang3.StringUtils.isBlank(source)) {
+                return null;
+            }
+            source = source.trim();
+            try {
+                SimpleDateFormat formatter;
+                if (source.contains("-")) {
+                    if (source.contains(":")) {
+                        formatter = new SimpleDateFormat(dateFormat);
+                    } else {
+                        formatter = new SimpleDateFormat(shortDateFormat);
+                    }
+                    return formatter.parse(source);
+                } else if (source.contains("/")) {
+                    if (source.contains(":")) {
+                        formatter = new SimpleDateFormat(dateFormat2);
+                    } else {
+                        formatter = new SimpleDateFormat(shortDateFormat2);
+                    }
+                    return formatter.parse(source);
+                }
+            } catch (Exception e) {
+                throw new RuntimeException(String.format("parser %s to Date fail", source));
+            }
+
+            throw new RuntimeException(String.format("parser %s to Date fail", source));
+        }
+    }
+
+}

+ 63 - 0
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/config/jackson/MappingJSONHttpMessageConverter.java

@@ -0,0 +1,63 @@
+package com.yonge.cooleshow.biz.dal.config.jackson;
+
+import com.alibaba.fastjson.JSON;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import com.microsvc.toolkit.common.response.template.ExtResponse;
+import com.microsvc.toolkit.common.response.template.JSONResponse;
+import com.microsvc.toolkit.common.response.template.Response;
+import com.microsvc.toolkit.common.response.template.SysResponse;
+import lombok.extern.slf4j.Slf4j;
+import org.springframework.http.HttpOutputMessage;
+import org.springframework.http.converter.HttpMessageNotWritableException;
+import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
+
+import java.io.IOException;
+import java.lang.reflect.Type;
+
+/**
+ * Created by Eric.Shang on 3/3/17.
+ */
+@Slf4j
+public class MappingJSONHttpMessageConverter extends MappingJackson2HttpMessageConverter {
+
+    public MappingJSONHttpMessageConverter() {
+    }
+
+    public MappingJSONHttpMessageConverter(ObjectMapper objectMapper) {
+        super(objectMapper);
+    }
+
+    /**
+     * 自定义JSON异常封装
+     * @param object Object
+     * @param type Type
+     * @param outputMessage HttpOutputMessage
+     * @throws IOException IOException
+     * @throws HttpMessageNotWritableException HttpMessageNotWritableException
+     */
+    @Override
+    protected void writeInternal(Object object, Type type, HttpOutputMessage outputMessage)
+            throws IOException, HttpMessageNotWritableException {
+
+        try {
+
+            if (object instanceof ExtResponse) {
+                // 拓展返回数据结构
+                object = ((ExtResponse<?>) object).data();
+
+            } else if (object instanceof Response) {
+                // 自定义标准数据结构
+                object = SysResponse.from((Response<?>) object);
+
+            } else if (object instanceof JSONResponse) {
+                // 三方标准数据结构,
+                object = JSON.toJSON(object);
+            }
+
+        } catch (Exception e) {
+            object = SysResponse.sysResponse();
+            log.error("jsonObject={}", object, e);
+        }
+        super.writeInternal(object, type, outputMessage);
+    }
+}

+ 105 - 16
cooleshow-user/user-biz/src/main/java/com/yonge/cooleshow/biz/dal/service/impl/CourseScheduleServiceImpl.java

@@ -12,35 +12,102 @@ import com.fasterxml.jackson.databind.ObjectMapper;
 import com.google.common.collect.Lists;
 import com.yonge.cooleshow.auth.api.client.SysUserFeignService;
 import com.yonge.cooleshow.auth.api.entity.SysUser;
-import com.yonge.cooleshow.biz.dal.dao.*;
+import com.yonge.cooleshow.biz.dal.dao.CourseScheduleDao;
+import com.yonge.cooleshow.biz.dal.dao.CourseScheduleRecordDao;
+import com.yonge.cooleshow.biz.dal.dao.CourseScheduleRepliedDao;
+import com.yonge.cooleshow.biz.dal.dao.CourseScheduleStudentPaymentDao;
+import com.yonge.cooleshow.biz.dal.dao.HolidaysFestivalsDao;
+import com.yonge.cooleshow.biz.dal.dao.PianoRoomTimeDao;
+import com.yonge.cooleshow.biz.dal.dao.TeacherFreeTimeDao;
+import com.yonge.cooleshow.biz.dal.dao.UserBindingTeacherDao;
 import com.yonge.cooleshow.biz.dal.dto.PracticeScheduleDto;
 import com.yonge.cooleshow.biz.dal.dto.UserAccountRecordDto;
 import com.yonge.cooleshow.biz.dal.dto.req.OrderReq;
 import com.yonge.cooleshow.biz.dal.dto.search.HomeworkSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.MyCourseSearch;
 import com.yonge.cooleshow.biz.dal.dto.search.PracticeTeacherSearch;
-import com.yonge.cooleshow.biz.dal.entity.*;
-import com.yonge.cooleshow.biz.dal.enums.*;
-import com.yonge.cooleshow.biz.dal.service.*;
+import com.yonge.cooleshow.biz.dal.entity.CourseCalendarEntity;
+import com.yonge.cooleshow.biz.dal.entity.CourseGroup;
+import com.yonge.cooleshow.biz.dal.entity.CourseSchedule;
+import com.yonge.cooleshow.biz.dal.entity.CourseScheduleDate;
+import com.yonge.cooleshow.biz.dal.entity.CourseScheduleRecord;
+import com.yonge.cooleshow.biz.dal.entity.CourseScheduleStudentPayment;
+import com.yonge.cooleshow.biz.dal.entity.CourseScheduleTeacherSalary;
+import com.yonge.cooleshow.biz.dal.entity.CourseTimeEntity;
+import com.yonge.cooleshow.biz.dal.entity.HolidaysFestivals;
+import com.yonge.cooleshow.biz.dal.entity.PianoRoomTime;
+import com.yonge.cooleshow.biz.dal.entity.PlatformCashAccountRecord;
+import com.yonge.cooleshow.biz.dal.entity.Student;
+import com.yonge.cooleshow.biz.dal.entity.TeacherFreeTime;
+import com.yonge.cooleshow.biz.dal.entity.TeacherSubjectPrice;
+import com.yonge.cooleshow.biz.dal.entity.UserBindingTeacher;
+import com.yonge.cooleshow.biz.dal.entity.UserOrderDetail;
+import com.yonge.cooleshow.biz.dal.enums.AccountBizTypeEnum;
+import com.yonge.cooleshow.biz.dal.enums.ClientEnum;
+import com.yonge.cooleshow.biz.dal.enums.CourseGroupEnum;
+import com.yonge.cooleshow.biz.dal.enums.CourseScheduleEnum;
+import com.yonge.cooleshow.biz.dal.enums.GoodTypeEnum;
+import com.yonge.cooleshow.biz.dal.enums.InOrOutEnum;
+import com.yonge.cooleshow.biz.dal.enums.MessageTypeEnum;
+import com.yonge.cooleshow.biz.dal.enums.OrderStatusEnum;
+import com.yonge.cooleshow.biz.dal.enums.RoomTypeEnum;
+import com.yonge.cooleshow.biz.dal.enums.SourceTypeEnum;
+import com.yonge.cooleshow.biz.dal.enums.TeacherSalaryEnum;
+import com.yonge.cooleshow.biz.dal.service.CourseGroupService;
+import com.yonge.cooleshow.biz.dal.service.CourseScheduleService;
+import com.yonge.cooleshow.biz.dal.service.CourseScheduleStudentPaymentService;
+import com.yonge.cooleshow.biz.dal.service.CourseScheduleTeacherSalaryService;
+import com.yonge.cooleshow.biz.dal.service.HolidaysFestivalsService;
+import com.yonge.cooleshow.biz.dal.service.ImGroupService;
+import com.yonge.cooleshow.biz.dal.service.ImUserFriendService;
+import com.yonge.cooleshow.biz.dal.service.LiveRoomService;
+import com.yonge.cooleshow.biz.dal.service.PlatformCashAccountRecordService;
+import com.yonge.cooleshow.biz.dal.service.RedisCacheService;
+import com.yonge.cooleshow.biz.dal.service.StudentService;
+import com.yonge.cooleshow.biz.dal.service.SysConfigService;
+import com.yonge.cooleshow.biz.dal.service.SysMessageService;
+import com.yonge.cooleshow.biz.dal.service.TeacherFreeTimeService;
+import com.yonge.cooleshow.biz.dal.service.TeacherService;
+import com.yonge.cooleshow.biz.dal.service.UserAccountRecordService;
+import com.yonge.cooleshow.biz.dal.service.UserAccountService;
+import com.yonge.cooleshow.biz.dal.service.UserOrderService;
+import com.yonge.cooleshow.biz.dal.support.WrapperUtil;
+import com.yonge.cooleshow.biz.dal.vo.ArrangeCourseVo;
+import com.yonge.cooleshow.biz.dal.vo.CountVo;
+import com.yonge.cooleshow.biz.dal.vo.CourseAdjustVo;
+import com.yonge.cooleshow.biz.dal.vo.CourseCompleteVo;
+import com.yonge.cooleshow.biz.dal.vo.CourseScheduleRecordVo;
+import com.yonge.cooleshow.biz.dal.vo.CourseScheduleStudentPaymentVo;
+import com.yonge.cooleshow.biz.dal.vo.CourseScheduleStudentVo;
+import com.yonge.cooleshow.biz.dal.vo.CourseStudent;
+import com.yonge.cooleshow.biz.dal.vo.CourseStudentVo;
+import com.yonge.cooleshow.biz.dal.vo.DateChangeVo;
+import com.yonge.cooleshow.biz.dal.vo.DateVo;
+import com.yonge.cooleshow.biz.dal.vo.MyCourseVo;
+import com.yonge.cooleshow.biz.dal.vo.PianoClassVo;
+import com.yonge.cooleshow.biz.dal.vo.PianoRoomTimeVo;
+import com.yonge.cooleshow.biz.dal.vo.PracticeTeacherVo;
+import com.yonge.cooleshow.biz.dal.vo.StudentHomePage;
+import com.yonge.cooleshow.biz.dal.vo.TeacherLiveCourseInfoVo;
+import com.yonge.cooleshow.biz.dal.vo.TodayNotRepliedAndNotDecorateHomeworkVo;
+import com.yonge.cooleshow.biz.dal.vo.UserAccountRecordVo;
+import com.yonge.cooleshow.biz.dal.vo.UserOrderDetailVo;
+import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
 import com.yonge.cooleshow.biz.dal.wrapper.UserPaymentOrderWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.course.CourseScheduleWrapper;
 import com.yonge.cooleshow.biz.dal.wrapper.liveroom.LiveRoomWrapper;
-import com.yonge.cooleshow.common.enums.PostStatusEnum;
-import com.yonge.cooleshow.common.enums.YesOrNoEnum;
-import com.yonge.toolset.payment.util.DistributedLock;
-import com.yonge.toolset.mybatis.support.PageUtil;
-import com.yonge.cooleshow.biz.dal.support.WrapperUtil;
-import com.yonge.cooleshow.biz.dal.vo.*;
-import com.yonge.cooleshow.biz.dal.vo.res.OrderCreateRes;
 import com.yonge.cooleshow.common.constant.SysConfigConstant;
 import com.yonge.cooleshow.common.entity.HttpResponseResult;
 import com.yonge.cooleshow.common.enums.CacheNameEnum;
+import com.yonge.cooleshow.common.enums.PostStatusEnum;
+import com.yonge.cooleshow.common.enums.YesOrNoEnum;
 import com.yonge.toolset.base.exception.BizException;
 import com.yonge.toolset.base.page.PageInfo;
+import com.yonge.toolset.mybatis.support.PageUtil;
+import com.yonge.toolset.payment.util.DistributedLock;
 import com.yonge.toolset.thirdparty.message.MessageSenderPluginContext;
 import com.yonge.toolset.utils.date.DateUtil;
 import com.yonge.toolset.utils.obj.ObjectUtil;
-
 import org.apache.commons.collections.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.redisson.api.RLock;
@@ -54,7 +121,6 @@ import org.springframework.transaction.annotation.Transactional;
 
 import java.math.BigDecimal;
 import java.math.RoundingMode;
-import java.text.MessageFormat;
 import java.text.SimpleDateFormat;
 import java.time.Instant;
 import java.time.LocalDate;
@@ -63,7 +129,19 @@ import java.time.ZoneId;
 import java.time.format.DateTimeFormatter;
 import java.time.temporal.ChronoUnit;
 import java.time.temporal.TemporalAdjusters;
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
 import java.util.concurrent.TimeUnit;
 import java.util.function.BiConsumer;
 import java.util.function.BiFunction;
@@ -535,10 +613,21 @@ public class CourseScheduleServiceImpl extends ServiceImpl<CourseScheduleDao, Co
             int weekNum = firstDay.getDayOfWeek().getValue();
             JSONArray jsonArray = teacherPracticeTime.get(weekNum);
             if (Objects.nonNull(jsonArray)) {
-                List<CourseTimeEntity> timeEntities = jsonArray.stream()
+
+                List<CourseTimeEntity> entities = Lists.newArrayList();
+                for (Object object : jsonArray) {
+                    if (object instanceof JSONObject) {
+                        entities.add(getCourseTimeEntity(entity, (JSONObject) object));
+                    }
+                }
+                List<CourseTimeEntity> timeEntities = entities.stream()
+                        .filter(x -> checkTime(x, star, end))
+                        .collect(Collectors.toList());
+
+                /*List<CourseTimeEntity> timeEntities = jsonArray.stream()
                         .map(t -> getCourseTimeEntity(entity, (JSONObject) t))
                         .filter(f -> checkTime(f, star, end))
-                        .collect(Collectors.toList());
+                        .collect(Collectors.toList());*/
                 entity.setCourseTime(timeEntities);
             }
             list.add(entity);

+ 1 - 1
cooleshow-websocket/pom.xml

@@ -82,7 +82,7 @@
         <dependency>
             <groupId>com.alibaba</groupId>
             <artifactId>fastjson</artifactId>
-            <version>1.2.68</version>
+            <version>2.0.9</version>
         </dependency>
     </dependencies>
 

+ 1 - 1
pom.xml

@@ -331,7 +331,7 @@
         <dependency>
             <groupId>com.alibaba</groupId>
             <artifactId>fastjson</artifactId>
-            <version>1.2.79</version>
+            <version>2.0.9</version>
         </dependency>
 	</dependencies>
 

+ 1 - 1
toolset/utils/pom.xml

@@ -95,7 +95,7 @@
         <dependency>
             <groupId>com.alibaba</groupId>
             <artifactId>fastjson</artifactId>
-            <version>1.2.70</version>
+            <version>2.0.9</version>
         </dependency>
 
         <dependency>

+ 20 - 21
toolset/utils/src/main/java/com/yonge/toolset/utils/http/HttpUtil.java

@@ -1,20 +1,8 @@
 package com.yonge.toolset.utils.http;
 
-import java.io.File;
-import java.io.FileOutputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.net.URLDecoder;
-import java.nio.charset.Charset;
-import java.security.KeyManagementException;
-import java.security.KeyStoreException;
-import java.security.NoSuchAlgorithmException;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
+import com.alibaba.fastjson.JSONArray;
+import com.alibaba.fastjson.JSONObject;
+import com.yonge.toolset.utils.compress.ZipUtil;
 import org.apache.commons.beanutils.ConvertUtils;
 import org.apache.commons.io.FileUtils;
 import org.apache.commons.io.IOUtils;
@@ -33,9 +21,20 @@ import org.apache.http.impl.client.HttpClients;
 import org.apache.http.message.BasicNameValuePair;
 import org.apache.http.util.EntityUtils;
 
-import com.alibaba.fastjson.JSONArray;
-import com.alibaba.fastjson.JSONObject;
-import com.yonge.toolset.utils.compress.ZipUtil;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URLDecoder;
+import java.nio.charset.Charset;
+import java.security.KeyManagementException;
+import java.security.KeyStoreException;
+import java.security.NoSuchAlgorithmException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
 
 public class HttpUtil {
 
@@ -54,7 +53,7 @@ public class HttpUtil {
 			HeadMap.put("Dwz-Token","0a9d3b34eae990d4355653d2ba6c8974");
 			HeadMap.put("Content-Type","application/json; charset=UTF-8");
 			HeadMap.put("Content-Language","zh");
-			String s = postForHttps("https://dwz.cn/api/v3/short-urls", jsonArray.toJSONString(),HeadMap);
+			String s = postForHttps("https://dwz.cn/api/v3/short-urls", jsonArray.toString(),HeadMap);
 			JSONObject result = JSONObject.parseObject(s);
 			String code=result.getString("Code");
 			if(code.equals("0")){
@@ -97,7 +96,7 @@ public class HttpUtil {
 	 * 
 	 * @param url
 	 *            URL
-	 * @param parameterMap
+	 * @param json
 	 *            请求参数
 	 * @return 返回结果
 	 * @throws IOException 
@@ -288,7 +287,7 @@ public class HttpUtil {
 	/**
 	 * post请求
 	 * @param url 请求地址
-	 * @param parameter 参数
+	 * @param parameterMap 参数
 	 * @param headers 头信息
 	 * @param fileMap 附件
 	 * @param contentType 附件的类型

+ 13 - 13
toolset/utils/src/main/java/com/yonge/toolset/utils/json/JsonUtil.java

@@ -1,13 +1,5 @@
 package com.yonge.toolset.utils.json;
 
-import java.lang.reflect.Type;
-import java.math.BigDecimal;
-import java.nio.charset.CharsetDecoder;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-
 import com.alibaba.fastjson.JSON;
 import com.alibaba.fastjson.JSONObject;
 import com.alibaba.fastjson.parser.Feature;
@@ -19,6 +11,14 @@ import com.alibaba.fastjson.serializer.SerializerFeature;
 import com.alibaba.fastjson.serializer.ValueFilter;
 import com.alibaba.fastjson.util.TypeUtils;
 
+import java.lang.reflect.Type;
+import java.math.BigDecimal;
+import java.nio.charset.CharsetDecoder;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+
 /**
  * 注意点: 如果存在对象间循环引用问题,解决办法: 将get方法的方法名非标准的名称,
  * 例如将getProductCategory()改成getproductCategory() 或者将属性定义加上transient关键字
@@ -127,8 +127,8 @@ public class JsonUtil {
 	}
 
 	private static String toJsonString(Object obj, ValueFilter filter) {
-		SerializeWriter out = new SerializeWriter(SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.QuoteFieldNames,
-				SerializerFeature.SkipTransientField, SerializerFeature.WriteEnumUsingToString, SerializerFeature.SortField);
+		// SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.QuoteFieldNames, SerializerFeature.SkipTransientField, SerializerFeature.WriteEnumUsingToString, SerializerFeature.SortField
+		SerializeWriter out = new SerializeWriter();
 		JSONSerializer serializer = new JSONSerializer(out);
 		serializer.config(SerializerFeature.WriteEnumUsingToString, false);
 		serializer.getValueFilters().add(filter);
@@ -149,7 +149,7 @@ public class JsonUtil {
 		List<T> objList = new ArrayList<T>();
 		if (jsonList != null && jsonList.size() > 0) {
 			for (int i = 0; i < jsonList.size(); i++) {
-				T val = TypeUtils.castToJavaBean(jsonList.get(i), clazz);
+				T val = TypeUtils.castToJavaBean(jsonList.get(i), clazz, null);
 				objList.add(val);
 			}
 		}
@@ -170,8 +170,8 @@ public class JsonUtil {
 
 	public static String toJSONString(Object object, SerializeConfig config, ValueFilter filter, SerializerFeature... features) {
 
-		SerializeWriter out = new SerializeWriter(SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteNullStringAsEmpty,
-				SerializerFeature.WriteMapNullValue, SerializerFeature.QuoteFieldNames, SerializerFeature.WriteNullNumberAsZero);
+		// SerializerFeature.DisableCircularReferenceDetect, SerializerFeature.WriteNullStringAsEmpty, SerializerFeature.WriteMapNullValue, SerializerFeature.QuoteFieldNames, SerializerFeature.WriteNullNumberAsZero
+		SerializeWriter out = new SerializeWriter();
 
 		JSONSerializer serializer = new JSONSerializer(out, config);
 		for (SerializerFeature feature : features) {