解決jackson反序列化失敗InvalidFormatException:Can not deserialize value of type java.util.Date
今天調(diào)試接口的時候碰到了這個問題,String 轉(zhuǎn)Date類型時
反序列化失敗
caused by: com.fasterxml.jackson.databind.exc.InvalidFormatException:
Can not deserialize value of type java.util.Date from String
“2018-12-25 10:07:49”: not a valid representation (error: Failed to
parse Date value ‘2018-12-25 10:07:49’: Can not parse date “2018-12-25
10:07:49Z”: while it seems to fit format
‘yyyy-MM-dd’T’HH:mm:ss.SSS’Z’’, parsing fails (leniency? null))
首先嘗試了 @DateTimeFormat注解,發(fā)現(xiàn)沒有效果,仍然報錯;
然后試了下@JsonFormat注解,接口正常;
在印象中,@DateTimeFormat是入?yún)r進(jìn)行數(shù)據(jù)格式化轉(zhuǎn)換,@JsonFormat是出參進(jìn)行格式話轉(zhuǎn)換,為啥突然不行了呢。
通過一番搜索,找到了如下解釋
一般都是使用@DateTimeFormat把傳給后臺的時間字符串轉(zhuǎn)成Date,使用@JsonFormat把后臺傳出的Date轉(zhuǎn)成時間字符串,但是@DateTimeFormat只會在類似@RequestParam的請求參數(shù)(url拼接的參數(shù)才生效,如果是放到RequestBody中的form-data也是無效的)上生效,如果@DateTimeFormat放到@RequestBody下是無效的。
在@RequestBody中則可以使用@JsonFormat把傳給后臺的時間字符串轉(zhuǎn)成Date,也就是說@JsonFormat其實既可以把傳給后臺的時間字符串轉(zhuǎn)成Date也可以把后臺傳出的Date轉(zhuǎn)成時間字符串。
至于為啥沒效果,沒有細(xì)說,從報錯的分析來看應(yīng)該是反序列話的方式不同,導(dǎo)致@DateTimeFormat注解不能生效。
另附原因與多種解決方式
原因
fastjson默認(rèn)使用的序列化格式:
public static String DEFFAULT_DATE_FORMAT = “yyyy-MM-dd HH:mm:ss”;
jackson默認(rèn)支持的日期反序列格式:
(“yyyy-MM-dd'T'HH:mm:ss.SSSZ”, “yyyy-MM-dd'T'HH:mm:ss.SSS'Z'”, “EEE,dd MMM yyyy HH:mm:ss zzz”, “yyyy-MM-dd”))
jackjson解析框架在解析實體類里面是date數(shù)據(jù)類型的數(shù)據(jù)時的默認(rèn)格式是:UTC類型,即yyyy-MM-dd’T’HH:mm:ss.SSS
并且默認(rèn)為+8時區(qū),即時間基礎(chǔ)上加8小時,
Springboot使用的默認(rèn)json解析框架是jackjson框架
解決辦法一
重寫jackson反序列化
import com.fasterxml.jackson.core.JsonParser;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
/**
* @version 1.0.0
* @description 重寫反序列化
* @date 2018/12/25 9:51
**/
public class CustomJsonDateDeserializer extends JsonDeserializer<Date> {
@Override
public Date deserialize(JsonParser jp, DeserializationContext ctxt) throws IOException, JsonProcessingException {
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
String date = jp.getText();
try {
return format.parse(date);
} catch (ParseException e) {
throw new RuntimeException(e);
}
}
}在需要的date屬性上添加注解:
@JsonDeserialize(using = CustomJsonDateDeserializer.class) private Date txnTime;
使用這種方式,需要重寫上面反序列化抽象類
解決辦法二
使用@JsonFormat注解指定所需的接收格式,不需要重寫反序列化:
//GMT+8表示時區(qū),東八區(qū),需加上時區(qū),shape 默認(rèn)是JsonFormat.Shape.ANY,
@JsonFormat(pattern = "yyyy-MM-dd HH:mm:ss", timezone = "GMT+8")
private Date txnTime;解決辦法三
如果排除了jackjson框架則使用fastjson注解,不要重寫反序列化
@JSONField(format = “yyyy-MM-dd HH:mm:ss”) private Date txnTime;
需要添加的依賴:
<!-- fastjson -->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>1.2.32</version>
</dependency>
<!-- jackson-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.6.4</version>
</dependency>最后介紹一種全局修改接收時間格式的方式
用MappingJackson2HttpMessageConverter配置在Application.Java啟動類,指定接收格式,本人不推薦使用,因為這是全局性的,不是很靈活,因此了解即可
@Bean
public MappingJackson2HttpMessageConverter getMappingJackson2HttpMessageConverter() {
MappingJackson2HttpMessageConverter mappingJackson2HttpMessageConverter = new MappingJackson2HttpMessageConverter();
//設(shè)置日期格式
ObjectMapper objectMapper = new ObjectMapper();
SimpleDateFormat smt = new SimpleDateFormat("yyyy-MM-dd");
objectMapper.setDateFormat(smt);
mappingJackson2HttpMessageConverter.setObjectMapper(objectMapper);
//設(shè)置中文編碼格式
List<MediaType> list = new ArrayList<MediaType>();
list.add(MediaType.APPLICATION_JSON_UTF8);
mappingJackson2HttpMessageConverter.setSupportedMediaTypes(list);
return mappingJackson2HttpMessageConverter;
}總結(jié)
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Spring?Cloud?OpenFeign模版化客戶端搭建過程
OpenFeign是一個顯示聲明式的WebService客戶端。使用OpenFeign能讓編寫Web Service客戶端更加簡單,這篇文章主要介紹了Spring?Cloud?OpenFeign模版化客戶端,需要的朋友可以參考下2022-06-06
@FeignClient的使用和Spring?Boot的版本適配方式
這篇文章主要介紹了@FeignClient的使用和Spring?Boot的版本適配方式,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-03-03
Windows中使用Java生成Excel文件并插入圖片的方法
這篇文章主要介紹了Windows中使用Java生成Excel文件并插入圖片的方法,其中向Excel中插入圖片文中通過使用Apache POI來實現(xiàn),需要的朋友可以參考下2016-02-02
Idea創(chuàng)建springboot不能選擇java8的解決
在IDEA 2023版本創(chuàng)建Spring Boot項目時,發(fā)現(xiàn)沒有Java 8選項,只有Java 17和Java 20,解決方法包括:通過修改服務(wù)器URL(推薦)或直接在創(chuàng)建后修改pom.xml文件中的Spring Boot和Java版本2025-01-01
Java代碼實現(xiàn)對properties文件有序的讀寫的示例
本篇文章主要介紹了Java代碼實現(xiàn)對properties文件有序的讀寫的示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-11-11
Spring-cloud-eureka使用feign調(diào)用服務(wù)接口
這篇文章主要為大家詳細(xì)介紹了Spring-cloud-eureka使用feign調(diào)用服務(wù)接口,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-04-04

