springboot 日期轉化報錯


問題場景:

使用Springboot框架搭建服務,傳日期參數json參數為2016-08-15 17:00:00這種格式,springboot中不能識別,將其轉化為對象對應的日期屬性。而是拋出異常信息,提示轉換失敗。

代碼:

傳參對應實體類

public class Demo {
    private String id;


    private Date date;

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }
}

controller

 @RequestMapping("/demo")
    public String demo(@RequestBody Demo demo) {
        System.out.println(demo.getId());
        return "this is client1";
    }

ajax調用使用的postman

請求報錯:

{
    "timestamp": "2018-09-17T14:01:00.278+0000",
    "status": 400,
    "error": "Bad Request",
    "message": "JSON parse error: Cannot deserialize value of type `java.util.Date` from String \"2018-09-17 21:46:08\": not a valid representation (error: Failed to parse Date value '2018-09-17 21:46:08': Cannot parse date \"2018-09-17 21:46:08\": while it seems to fit format 'yyyy-MM-dd'T'HH:mm:ss.SSSZ', parsing fails (leniency? null)); nested exception is com.fasterxml.jackson.databind.exc.InvalidFormatException: Cannot deserialize value of type `java.util.Date` from String \"2018-09-17 21:46:08\": not a valid representation (error: Failed to parse Date value '2018-09-17 21:46:08': Cannot parse date \"2018-09-17 21:46:08\": while it seems to fit format 'yyyy-MM-dd'T'HH:mm:ss.SSSZ', parsing fails (leniency? null))\n at [Source: (PushbackInputStream); line: 3, column: 9] (through reference chain: com.hanggle.eurekaclient.Demo[\"date\"])",
    "path": "/demo"
}

錯誤原因是日期轉換失敗,由於springboot默認采用jackson,而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類型的時間戳(毫秒時間戳)

不能識別yyyy-MM-dd HH:mm:ss類似格式的數據,所以轉換失敗。 

解決辦法有以下幾種:

1. 采用long時間戳(毫秒時間戳!!!!)如:1537191968000 

2.在傳參的對象上加上@JsonFormat注解並且指定時區(此方法治標不治本)

@JsonFormat(locale="zh", timezone="GMT+8", pattern="yyyy-MM-dd HH:mm:ss")

如果項目中使用json解析框架為fastjson框架,則可使用如下解決方法:
在實體字段上使用@JsonFormat注解格式化日期

@JsonFormat(shape=JsonFormat.Shape.STRING, pattern="yyyy-MM-dd HH:mm:ss")

 

3、采用全局處理方式統一處理,推薦這個做法

重寫springboot默認轉換

 參考:https://blog.csdn.net/qq906627950/article/details/79503801

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

    // 這里裝飾clone方法的原因是因為clone方法在jackson中也有用到
    @Override
    public Object clone() {
        Object format = dateFormat.clone();
        return new MyDateFormat((DateFormat) format);
    }


}

 

@Configuration
public class WebConfig {

    @Autowired
    private Jackson2ObjectMapperBuilder jackson2ObjectMapperBuilder;

    @Bean
    public MappingJackson2HttpMessageConverter MappingJsonpHttpMessageConverter() {

        ObjectMapper mapper = jackson2ObjectMapperBuilder.build();

        // ObjectMapper為了保障線程安全性,里面的配置類都是一個不可變的對象
        // 所以這里的setDateFormat的內部原理其實是創建了一個新的配置類
        DateFormat dateFormat = mapper.getDateFormat();
        mapper.setDateFormat(new MyDateFormat(dateFormat));

        MappingJackson2HttpMessageConverter mappingJsonpHttpMessageConverter = new MappingJackson2HttpMessageConverter(
                mapper);
        return mappingJsonpHttpMessageConverter;
    }

}

 

 參考資料:

https://blog.csdn.net/pp_fzp/article/details/79588374

https://blog.csdn.net/qq906627950/article/details/79503801

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM