背景

  1. 问题1:项目中使用默认自带的jackson进行前后端交互,实现数据对象的序列化和反序列化,默认的ObjectMapper采用小驼峰的格式,但是调用其他业务的http接口时,ObjectMapper需要使用蛇形的格式,因此就需要自定义ObjectMapper,然后封装RestTemplate。
  2. 问题2:前后端交互时,JSR310日期序列化时,格式错误;使用springboot自带的jackson,是不支持JSR310的日期,需要全局配置

注意点

  1. 自定义的ObjectMapper不能被IOC管理,因为Springboot默认的ObjectMapper生成条件是:只有当该实例不存在的时候才会创建!
  2. 自定义时,需要支持JSR310的日期,否则序列化LocalDateTime、LocalDate、LocalTime时,就会返回错误的格式。

自定义ObjectMapper

@Slf4j
public class JsonFormatUtils {
private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss");
public static final ObjectMapper objectMapper = new ObjectMapper(); static {
//取消时间的转化格式,默认是时间戳,同时需要设置要表现的时间格式
objectMapper.configure(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS, false);
objectMapper.configure(SerializationFeature.WRITE_DURATIONS_AS_TIMESTAMPS, false);
objectMapper.setDateFormat(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"));
JavaTimeModule javaTimeModule = new JavaTimeModule(); // 默认序列化没有实现,反序列化有实现
javaTimeModule.addSerializer(LocalDateTime.class, new LocalDateTimeSerializer(DATE_TIME_FORMATTER));
javaTimeModule.addSerializer(LocalDate.class, new LocalDateSerializer(DATE_FORMATTER));
javaTimeModule.addSerializer(LocalTime.class, new LocalTimeSerializer(TIME_FORMATTER));
objectMapper.registerModule(javaTimeModule);
// 设置时区
objectMapper.setTimeZone(TimeZone.getDefault());
// 设置格式化输出
// objectMapper.enable(SerializationFeature.INDENT_OUTPUT);
// 设置蛇形格式
objectMapper.setPropertyNamingStrategy(PropertyNamingStrategy.SNAKE_CASE);
} public static String writeValueAsString(Object obj) {
String result = null;
try {
result = objectMapper.writeValueAsString(obj);
} catch (JsonProcessingException e) {
log.error("objectMapper writeValueAsString exception, e:", e);
}
return result;
} public static <T> T readValue(String str, Class<T> tClass) {
T t = null;
try {
t = objectMapper.readValue(str, tClass);
} catch (JsonProcessingException e) {
log.error("objectMapper readValue exception, e:", e);
}
return t;
}
}

封装RestTemplate

@Configuration
public class RestTemplateConfig {
@Bean("otherRestTemplate")
public RestTemplate algoRestTemplate() {
// 使用apache的httpComponents,封装restTemplate
ClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory(httpClient());
RestTemplate restTemplate = new RestTemplate(factory);
// 使用自定义的ObjectMapper
ObjectMapper objectMapper = JsonFormatUtils.objectMapper;
MappingJackson2HttpMessageConverter messageConverter = new MappingJackson2HttpMessageConverter();
messageConverter.setPrettyPrint(false);
messageConverter.setObjectMapper(objectMapper); List<HttpMessageConverter<?>> messageConverters = restTemplate.getMessageConverters();
messageConverters.removeIf(item -> item.getClass().getName().equals(MappingJackson2HttpMessageConverter.class.getName()));
messageConverters.add(messageConverter);
return restTemplate;
} private HttpClient httpClient() {
PoolingHttpClientConnectionManager connectionManager = new PoolingHttpClientConnectionManager();
connectionManager.setMaxTotal(50);
connectionManager.setDefaultMaxPerRoute(10);
connectionManager.setValidateAfterInactivity(2000);
RequestConfig requestConfig = RequestConfig.custom()
.setSocketTimeout(10000)
.setConnectTimeout(5000)
.setConnectionRequestTimeout(1000)
.build();
return HttpClientBuilder.create().setDefaultRequestConfig(requestConfig).setConnectionManager(connectionManager).build();
}
}

全局配置

底层默认是通过Jackson2ObjectMapperBuilderCustomizer创建的ObjectMapper

@Configuration
public class LocalDateTimeSerializerConfig { private static final DateTimeFormatter DATE_TIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
private static final DateTimeFormatter DATE_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd");
private static final DateTimeFormatter TIME_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss"); @Bean
public Jackson2ObjectMapperBuilderCustomizer jackson2ObjectMapperBuilderCustomizer() {
Map<Class<?>, JsonSerializer<?>> serializers = new HashMap<>();
serializers.put(LocalDateTime.class, new LocalDateTimeSerializer(DATE_TIME_FORMATTER));
serializers.put(LocalDate.class, new LocalDateSerializer(DATE_FORMATTER));
serializers.put(LocalTime.class, new LocalTimeSerializer(TIME_FORMATTER)); Map<Class<?>, JsonDeserializer<?>> deserializers = new HashMap<>();
deserializers.put(LocalDateTime.class, new LocalDateTimeDeserializer(DATE_TIME_FORMATTER));
deserializers.put(LocalDate.class, new LocalDateDeserializer(DATE_FORMATTER));
deserializers.put(LocalTime.class, new LocalTimeDeserializer(TIME_FORMATTER));
return builder -> builder.serializersByType(serializers).deserializersByType(deserializers);
}
}

最新文章

  1. C#把 DataTable转换为Model实体
  2. SQL链接服务器
  3. 使用Struts 2防止表单重复提交
  4. codevs1064 虫食算
  5. 【转】这些编程语言程序员工资最高!Java才第四
  6. spring quartz的触发器CrontriggerBean配置
  7. Android恢复出厂设置流程分析【Android源码解析十】
  8. greenlet微线程
  9. AtCoder ABC 042D いろはちゃんとマス目 / Iroha and a Grid
  10. 删除CSDN点击“阅读更多”按钮跳转到登录界面的功能
  11. Mysql加锁过程详解(3)-关于mysql 幻读理解
  12. Spark 精品文章转载(目录)
  13. 新系统centos7重启网络报错
  14. python中argparse
  15. Zabbix使用Omsa来监控Dell服务器的硬件状态
  16. 词组查询以及多值映射等SolrNet使用中的细节问题
  17. ng-include 上ng-controller 无法获取控件
  18. 第一章 EL表达式常见用法
  19. javaweb经典面试题
  20. String和StringBuffer以及StringBuilder的区别

热门文章

  1. Linux基本命令精讲
  2. UnityPlayerActivity.java使用或覆盖了已过时的 API。
  3. 富文本编辑器之游戏角色升级ing
  4. Linux定时任务-cronie
  5. 9、ssh服务详解及优化
  6. 精尽Spring Boot源码分析 - @ConfigurationProperties 注解的实现
  7. 『无为则无心』Python函数 — 27、Python函数的返回值
  8. Docker:docker部署Tomcat运行web项目
  9. 小白都能理解的TCP三次握手四次挥手
  10. uni-app中当uni.navigateTo传的参数为object时,通过传递的不同参数,在显示单页面内通过v-if判断显示出对应的内容(可实现多页面效果)