差異處

這裏顯示兩個版本的差異處。

連向這個比對檢視

java:jackson:annotation:jsonserialize:convertdate [2016/03/11 00:12]
tony
java:jackson:annotation:jsonserialize:convertdate [2023/06/25 09:48]
行 1: 行 1:
-{{tag>​java jackson}} 
-====== Convert the Date format to ISO8601 ====== 
-===== Problem ===== 
-在做Rest API的輸出處理時,一定會遇到日期要顯示的格式,而日期也伴隨著timezone的問題。要顯示成甚麼樣子的格式,就看各個應用程式的需求。一開始是想仿效臉書轉為unix time,後來再為這問題爭論不休;最後我在study後,認為ISO8601比較符合我們需求,就決定為我們的顯示格式。 
-===== How to? ===== 
-預設使用Jackson去做Date的轉換,會輸出為unix time。如果要達到我們的目的,可透過@JsonSerialize設定對應序列化的物件;而要接收使用者輸入轉為對應物件的話,可透過@JsonDeserialize設定對應反序列化物件。 
-==== Object with JsonSerialize and JsonDeserialize annotation ==== 
-<code java> 
-public class Event { 
- @JsonSerialize(using=ISO8601DateSerializer.class) 
- @JsonDeserialize(using=ISO8601DateDeserializer.class) 
- private Date date; 
-  
- private String message; 
-  
- public Date getDate(){ 
- return date; 
- } 
-  
- public void setDate(Date date){ 
- this.date = date; 
- } 
-  
-        // ... skip 
-} 
-</​code>​ 
-==== ISO8601DateSerializer for Date ==== 
-<code java> 
-public class ISO8601DateSerializer extends StdSerializer<​Date>​ { 
- private static final long serialVersionUID = 1L; 
  
- public ISO8601DateSerializer() { 
- super(Date.class);​ 
- } 
- 
- @Override 
- public void serialize(Date date, JsonGenerator json, 
- SerializerProvider provider) throws IOException,​ 
- JsonGenerationException { 
- DateFormat df = StdDateFormat.getISO8601Format( 
- TimeZone.getTimeZone("​UTC"​),​ Locale.getDefault());​ 
- String out = df.format(date);​ 
- 
- 
- json.writeString(out);​ 
- } 
- 
-} 
-</​code>​ 
-==== ISO8601DateDeserializer for Date ==== 
-<code java> 
-public class ISO8601DateDeserializer extends StdDeserializer<​Date>​ { 
- 
- private static final long serialVersionUID = 1L; 
- 
- public ISO8601DateDeserializer() { 
-        super(Date.class);​ 
-    } 
- 
- @Override 
- public Date deserialize(JsonParser parser, DeserializationContext context) 
- throws IOException,​ JsonProcessingException { 
- try { 
- 
- DateFormat df = StdDateFormat.getISO8601Format( 
- TimeZone.getTimeZone("​UTC"​),​ Locale.getDefault());​ 
- return df.parse(parser.getText());​ 
- } catch (Exception e) { 
- return null; 
- } 
- } 
-} 
-</​code>​ 
-==== Convert to Json ==== 
-簡單寫一個測試案例,去驗證序列化後再反序列化的內容會一致:​ 
-<code java> 
- @Test 
- public void testDateWithAnnotation() throws Exception { 
- ObjectMapper mapper = new ObjectMapper();​ 
- 
- Date d = new Date(); 
- Event e = new Event(); 
- e.setDate(d);​ 
- 
- String ret = mapper.writeValueAsString(e);​ 
- System.out.println(ret);​ 
- Event newEvent = mapper.readValue(ret,​ Event.class);​ 
- assertEquals(d.getTime(),​ newEvent.getDate().getTime());​ 
- } 
-</​code>​ 
-output: 
-<​code>​ 
-{"​date":"​2016-03-10T15:​40:​11.869+0000","​message":​null} 
-</​code>​ 
-==== Apply to all Date fields ==== 
-上面所敘述的是透過在欄位宣告@JsonSerialize,來達到我們的目的。如果想要讓每一個擁有Date的bean物件都能使用這個格式,可以透過Jackson所提供的Module功能,去設定對應物件的Serializer與Deserializer:​ 
-<code java> 
-ObjectMapper mapper = new ObjectMapper();​ 
- 
-SimpleModule m = new SimpleModule();​ 
-m.addSerializer(Date.class,​ new ISO8601DateSerializer());​ 
-m.addDeserializer(Date.class,​ new ISO8601DateDeserializer());​ 
-  
-mapper.registerModule(m);​ 
-</​code>​ 
- 
-===== Reference ===== 
-  * [[http://​stackoverflow.com/​questions/​5471379/​ways-to-convert-unix-linux-time-to-windows-time|ways-to-convert-unix-linux-time-to-windows-time]] 
-  * [[https://​zh.wikipedia.org/​wiki/​ISO_8601|ISO8601]] 
-  * [[http://​nbsoftsolutions.com/​blog/​designing-a-rest-api-unix-time-vs-iso-8601|Designing a REST API: Unix time vs ISO-8601]] 
- 
- 
- 
-=====    ===== 
----- 
-\\ 
-~~DISQUS~~