解决fegin 日期转换 com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of

环境:

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);

    }

猜你喜欢

转载自blog.csdn.net/xtj332/article/details/84570181