环境:
springCloud fegin调用
服务端:
返回了一个JSON对象,其中有一个createTime字段,格式是'yyyy-MM-dd HH:mm:ss'。
客户端:
使用对象整体接收参数,其中createTime字段对应类型是java.sql.Timestamp。
报错:
com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of ......
解决方案一:
import java.text.*;
import java.util.Date;
/**
* @author
* @date 2018/11/27 15:06
*/
public class MyDateFormat extends DateFormat {
private DateFormat dateFormat;
private SimpleDateFormat format1 = new SimpleDateFormat("yyy-MM-dd HH:mm:ss");
public MyDateFormat(DateFormat dateFormat) {
this.dateFormat = dateFormat;
}
@Override
public StringBuffer format(Date date, StringBuffer toAppendTo, FieldPosition fieldPosition) {
return dateFormat.format(date, toAppendTo, fieldPosition);
}
@Override
public Date parse(String source, ParsePosition pos) {
Date date = null;
try {
date = format1.parse(source, pos);
} catch (Exception e) {
date = dateFormat.parse(source, pos);
}
return date;
} // 主要还是装饰这个方法
@Override
public Date parse(String source) throws ParseException {
Date date = null;
try {
// 先按我的规则来
date = format1.parse(source);
} catch (Exception e) { // 不行,那就按原先的规则吧
date = dateFormat.parse(source);
}
return date;
}
}
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializerProvider;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.json.Jackson2ObjectMapperBuilder;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import java.io.IOException;
import java.text.DateFormat;
@Configuration
public class JacksonConfig {
@Autowired
Jackson2ObjectMapperBuilder builder;
@Bean
@ConditionalOnMissingBean(ObjectMapper.class)
public ObjectMapper jacksonObjectMapper() {
ObjectMapper objectMapper = builder.createXmlMapper(false).build();
// 通过该方法对mapper对象进行设置,所有序列化的对象都将按改规则进行系列化
// Include.Include.ALWAYS 默认
// Include.NON_DEFAULT 属性为默认值不序列化
// Include.NON_EMPTY 属性为 空("") 或者为 NULL 都不序列化,则返回的json是没有这个字段的。这样对移动端会更省流量
// Include.NON_NULL 属性为NULL 不序列化,就是为null的字段不参加序列化
// objectMapper.setSerializationInclusion(Include.NON_EMPTY);
// 字段保留,将null值转为""
objectMapper.getSerializerProvider().setNullValueSerializer(new JsonSerializer<Object>() {
@Override
public void serialize(Object o, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException {
jsonGenerator.writeString("");
}
});
return objectMapper;
}
@Bean
public MappingJackson2HttpMessageConverter MappingJsonpHttpMessageConverter() {
ObjectMapper mapper = jacksonObjectMapper();
// ObjectMapper为了保障线程安全性,里面的配置类都是一个不可变的对象
// 所以这里的setDateFormat的内部原理其实是创建了一个新的配置类
DateFormat dateFormat = mapper.getDateFormat();
MyDateFormat dateFormat1 = new MyDateFormat(dateFormat);
BeanUtils.copyProperties(dateFormat,dateFormat1);
mapper.setDateFormat(dateFormat1);
MappingJackson2HttpMessageConverter mappingJsonpHttpMessageConverter = new MappingJackson2HttpMessageConverter(
mapper);
return mappingJsonpHttpMessageConverter;
}
问题解决。测试可用。
参考了:https://blog.csdn.net/qq906627950/article/details/79503801
和原解决方案大致思路一致,但是原方案有问题,直接使用会报错,我这边做了优化。
解决方案二:
使用FastJson替换jackson。
@Configuration
public class WebMvcConfigurerImpl implements WebMvcConfigurer {
@Bean
public HttpMessageConverters fastjsonHttpMessageConverter(){
//定义一个转换消息的对象
FastJsonHttpMessageConverter fastConverter = new FastJsonHttpMessageConverter();
//添加fastjson的配置信息 比如 :是否要格式化返回的json数据
FastJsonConfig fastJsonConfig = new FastJsonConfig();
fastJsonConfig.setSerializerFeatures(SerializerFeature.PrettyFormat);
//在转换器中添加配置信息
fastConverter.setFastJsonConfig(fastJsonConfig);
HttpMessageConverter<?> converter = fastConverter;
return new HttpMessageConverters(converter);
}