Spring中存在兩個地方可以設置日期格式,一個是 spring.mvc.date-format,還有一個是spring.jackson.date-format。現在說說他們的區別。
spring.mvc.date-format
spring.mvc.date-format是針對x-www-form-urlencoded這種編碼的數據,也就是通過表單<form>上傳上來的數據。
我們假設Java的代碼是這樣,並且在localhost:80監聽:
//POJO
pubulic class OneDate{
private String name;
private Date date;
//省略函數
}
//Controller
@Controller
public class OneController{
@RequestMapping("/up")
public String getDate(OneDate d){
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
System.out.println(format.format(d));
return "onePage";
}
}
這是我們使用curl進行測試。
以下可以通過:
#POST
curl -X POST -d 'name=build&date=2000/1/2' 'http://localhost/up'
curl -X POST -d 'name=build&date=2000/1/2 14:32:56' 'http://localhost/up'
curl -X POST -d 'name=build&date=2000/1/2 14:32:56 GMT' 'http://localhost/up'
curl -X POST -d 'name=build&date=Jan 2 2000 14:32:56 GMT' 'http://localhost/up'
# 使用GET也是一樣的
curl 'http://localhost/json?name=build&date=2000/2/3%2014:32:56'
但是使用橫杠分割就不行。
curl -X POST -d 'name=build&date=2000-1-2 14:32:56' 'http://localhost/up'
# 這里會返回錯誤信息: Failed to convert from type [java.lang.String] to type [java.util.Date]
這里的原理是,當沒有配置spring.mvc.date-format這個選項時,spring會使用Date的一個廢棄的構造函數
@Deprecated
public Date(String s) {
this(parse(s));
}
來進行字符串到日期的轉換。能否轉換成功取決於這個parse函數。所以還是應該顯式地設置好這個配置項。
注意!設置好后,默認的parse就不會生效了,只會使用設置的格式。
這里不設置時區的話,就會使用服務端的本地時區。所以完美一點的話,應該在格式中把時區也加上。
spring.jackson.date-format
spring.jackson.date-format則是設置識別HTTP請求的body中的日期字符串的格式。對應的類型是application/json。
假設我們有這樣的Java代碼(POJO同上):
@Controller
public class OneController2{
@PostMapping("/up")
public String getDate2(@RequestBody OneDate d){
SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss Z");
System.out.println(format.format(d));
return "onePage";
}
}
然后我們用curl繼續測試。
curl -X POST -d '{"name":"build","date":"2020/2/12"}' -H "Content-Type: application/json" 'http://localhost/up'
這個語句會返回錯誤(沒想到吧?json這里默認不是用斜線!和之前的不一樣!)
錯誤語句說: Cannot parse date \"2020/2/12\": not compatible with any of standard forms (\"yyyy-MM-dd'T'HH:mm:ss.SSSZ\", \"yyyy-MM-dd'T'HH:mm:ss.SSS\", \"EEE, dd MMM yyyy HH:mm:ss zzz\", \"yyyy-MM-dd\"));
可以看出jackson里的設置了四個格式。如果都不匹配則會報錯。
正確的示例如下:
"2020-2-2" #僅日期,對應yyyy-MM-dd
# 對應 EEE, dd MMM yyyy HH:mm:ss zzz ,
“Wed, 12 Feb 2020 13:45:56 GMT” # 對應JS中的toGMTString()
“Wed, 12 Feb 2020 13:45:56 +0800”
# 對應 yyyy-MM-dd'T'HH:mm:ss.SSS
“2020-02-03T13:45:56.142” # 這里不能寫成2020-2-3
# 對應 yyyy-MM-dd'T'HH:mm:ss.SSSZ ,對應JS的toISOString()
“2020-02-03T13:45:56.142Z” # Z代表0時區,中國是+8時區
注意!與上一節不同,jackson里不寫時區,默認就是0時區。
想要設置默認時區,使用spring.jackson.time-zone=GMT+8
