Fegin调用时,Jackson时间转换异常问题解决

最近在用fegin调用的时候发现一个问题,很多时间格式jackson在字符串转date的时候不支持,会报错。
报错信息如下:

feign.codec.DecodeException: Error while extracting response for type [com.inforun.common.core.domain.R<java.util.List<com.inforun.common.base.domain.TTaskTime>>] and content type [application/json;charset=UTF-8]; nested exception is org.springframework.http.converter.HttpMessageNotReadableException: JSON parse error: Cannot deserialize value of type `java.util.Date` from String "23:59:59": not a valid representation (error: Failed to parse Date value '23:59:59': Unparseable date: "23:59:59"); nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.util.Date` from String "23:59:59": not a valid representation (error: Failed to parse Date value '23:59:59': Unparseable date: "23:59:59")
 at [Source: (PushbackInputStream); line: 1, column: 82] (through reference chain: com.inforun.common.core.domain.R["data"]->java.util.ArrayList[0]->com.inforun.common.base.domain.TTaskTime["endTime"])

我这个是只要时间,还有只要日期的,在转换的时候都不行,在网上查了资料后才知道,jackson只支持下面几种类型

"yyyy-MM-dd'T'HH:mm:ss.SSSZ";

"yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";

"yyyy-MM-dd";

"EEE, dd MMM yyyy HH:mm:ss zzz";

long类型的时间戳

这些类型里面明显不包括我传入的格式,所以只能自己去想办法解决,一共有两种办法来解决。

一、注解解决方式,在单个的类上加注解
在这里插入图片描述
但是这种方式只能用于少数,如果很多的话一个个加也很麻烦,所以我没有用这种方式。

二、自定义类型转换器方式
我们可以写一个自定义时间类型转换器,用时间类型转换器去转换我们需要的格式,这样也就不需要一个个加注解了,比较方便。

import cn.hutool.core.date.DateUtil;

import java.text.DateFormat;
import java.text.FieldPosition;
import java.text.ParseException;
import java.text.ParsePosition;
import java.text.SimpleDateFormat;
import java.util.Date;

public class MyDateFormat extends DateFormat {
    
    
    private DateFormat dateFormat;
    private SimpleDateFormat format1 = new SimpleDateFormat("yyy-MM-dd HH:mm:ss");
    private SimpleDateFormat format2 = new SimpleDateFormat("yyy-MM-dd");
    private SimpleDateFormat format3 = new SimpleDateFormat("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 {
    
    
            // 先按我的规则1来
            date = format1.parse(source, pos);
        } catch (Exception e) {
    
    
            //方式1不行方式2
            try {
    
    
                date = format2.parse(source, pos);
            } catch (Exception e1) {
    
    
                //方式2不行方式3
                try {
    
    
                    date = format3.parse(source, pos);
                } catch (Exception e2) {
    
    
                    // 不行,那就按原先的规则吧
                    date = dateFormat.parse(source, pos);
                }
            }
        }
        return date;
    }    // 主要还是装饰这个方法

    @Override
    public Date parse(String source) throws ParseException {
    
    
        Date date = null;
        try {
    
    
            //先按照自己的规则来,动态筛查
            date = DateUtil.parse(source);
        } catch (Exception e) {
    
    
            // 不行,那就按原先的规则吧
            date = dateFormat.parse(source);
        }
        return date;
    }    // 这里装饰clone方法的原因是因为clone方法在jackson中也有用到

    @Override
    public Object clone() {
    
    
        Object format = dateFormat.clone();
        return new MyDateFormat((DateFormat) format);
    }
}

这是自定义的转换类,其实我们用的还是单个转换的,我这里在单个转换的时候用了Hutool的工具类,他可以自动识别一些常用的时间类型,这样省的自己去定义了,接下来我们配置一下就可以了。

import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.inforun.common.security.config.jackson.MyDateFormat;
import com.inforun.common.security.interceptor.HeaderInterceptor;
import org.springframework.context.annotation.Bean;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.servlet.config.annotation.InterceptorRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.text.DateFormat;

public class WebMvcConfig implements WebMvcConfigurer
{
    
    

    @Bean
    public MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter(){
    
    

        MappingJackson2HttpMessageConverter converter = new MappingJackson2HttpMessageConverter();
        ObjectMapper objectMapper = new ObjectMapper();
        //添加此配置
        objectMapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
        converter.setObjectMapper(objectMapper);
        DateFormat dateFormat = objectMapper.getDateFormat();
        objectMapper.setDateFormat(new MyDateFormat(dateFormat));
        return converter;
    }
}

至此就算完成了,再去转换的时候就没有问题了,大家可以试一试。

猜你喜欢

转载自blog.csdn.net/qq_45699784/article/details/131044965
今日推荐