差異處
這裏顯示兩個版本的差異處。
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~~ |