问题1:项目中使用默认自带的jackson进行前后端交互,实现数据对象的序列化和反序列化,默认的ObjectMapper采用小驼峰的格式,但是调用其他业务的http接口时,ObjectMapper需要使用蛇形的格式,因此就需要自定义ObjectMapper,然后封装RestTemplate。
问题2:前后端交互时,JSR310日期序列化时,格式错误;使用springboot自带的jackson,是不支持JSR310的日期,需要全局配置
注意点自定义的ObjectMapper不能被IOC管理,因为Springboot默认的ObjectMapper生成条件是:只有当该实例不存在的时候才会创建!
自定义时,需要支持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); } }