Jackson的使用和JSON日期型別的顯示

pucheung發表於2015-04-28

@JsonAutoDetect (class)

這是作用於類的annotation,主要用於指明該類使用annotation,並且可以自動偵測getter,setter,構造方法,以便生成json物件

@JsonIgnore (method/field):作用於方法或欄位,用來表明,當生成json的時候忽略有該annotation的方法或欄位

 

如題,以一個使用者物件為例子:

 

Java程式碼 複製程式碼
  1. @Entity  
  2. @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)   
  3. @JsonAutoDetect  
  4. /**  
  5. * 在此標記不生成json物件的屬性,這裡我標記了兩個屬性一個hibernateLazyInitializer屬性,為什麼要標記這個  
  6. * 屬性參考前面的博文,一個password屬性,出於安全這個當然不能轉換成json物件了,畢竟json是在前臺呼叫的,  
  7. * 如果你想轉換的時候忽略某個屬性,可以在後面繼續加上  
  8. */  
  9. @JsonIgnoreProperties(value = {"hibernateLazyInitializer""password"})   
  10. public class User   
  11. {   
  12.     private Long id;   
  13.     private String name;   
  14.     private String password;   
  15.     private String email;   
  16.     private Date createAt;   
  17.     @Id  
  18.     @GeneratedValue(strategy = GenerationType.IDENTITY)   
  19.     public Long getId() {   
  20.         return id;   
  21.     }   
  22.   
  23.     public void setId(Long id) {   
  24.         this.id = id;   
  25.     }   
  26.     /**  
  27.     * 轉換日期物件的輸出格式,CustomDateSerializer 程式碼參考前面的博文      
  28.         */  
  29.     @JsonSerialize(using = CustomDateSerializer.class)   
  30.     public Date getCreateAt() {   
  31.             return createAt;   
  32.     }   
  33.   
  34.     public void setCreateAt(Date createAt) {   
  35.             this.createAt = createAt;   
  36.     }   
  37.     /**  
  38.     * 其他的getter和setter省略  
  39.     */  
  40. }  
Java程式碼  收藏程式碼
  1. @Entity  
  2. @Cache(usage = CacheConcurrencyStrategy.READ_WRITE)  
  3. @JsonAutoDetect  
  4. /** 
  5. * 在此標記不生成json物件的屬性,這裡我標記了兩個屬性一個hibernateLazyInitializer屬性,為什麼要標記這個 
  6. * 屬性參考前面的博文,一個password屬性,出於安全這個當然不能轉換成json物件了,畢竟json是在前臺呼叫的, 
  7. * 如果你想轉換的時候忽略某個屬性,可以在後面繼續加上 
  8. */  
  9. @JsonIgnoreProperties(value = {"hibernateLazyInitializer""password"})  
  10. public class User  
  11. {  
  12.     private Long id;  
  13.     private String name;  
  14.     private String password;  
  15.     private String email;  
  16.     private Date createAt;  
  17.     @Id  
  18.     @GeneratedValue(strategy = GenerationType.IDENTITY)  
  19.     public Long getId() {  
  20.         return id;  
  21.     }  
  22.   
  23.     public void setId(Long id) {  
  24.         this.id = id;  
  25.     }  
  26.     /** 
  27.     * 轉換日期物件的輸出格式,CustomDateSerializer 程式碼參考前面的博文     
  28.         */  
  29.     @JsonSerialize(using = CustomDateSerializer.class)  
  30.     public Date getCreateAt() {  
  31.             return createAt;  
  32.     }  
  33.   
  34.     public void setCreateAt(Date createAt) {  
  35.             this.createAt = createAt;  
  36.     }  
  37.     /** 
  38.     * 其他的getter和setter省略 
  39.     */  
  40. }  

 

至於中間的什麼service,dao都大同小異就不記錄了

轉到struts2 看看一個用jackson返回json物件的action是如何寫的

Java程式碼 複製程式碼
  1. @Namespace("/security/user")   
  2. public class UserAction extends ActionSupport   
  3. {   
  4.     @Action("list")   
  5.     public String list() throws Exception {   
  6.             // 取得所有的使用者   
  7.             List<User> list = userService.getAll();   
  8.             response = ServletActionContext.getResponse();   
  9.             // jackson   
  10.             ObjectMapper mapper = new ObjectMapper();   
  11.             // 把取得的使用者list寫入response   
  12.             mapper.writeValue(response.getWriter(), list);   
  13.             return null;   
  14.     }   
  15. }  
Java程式碼  收藏程式碼
  1. @Namespace("/security/user")  
  2. public class UserAction extends ActionSupport  
  3. {  
  4.     @Action("list")  
  5.     public String list() throws Exception {  
  6.             // 取得所有的使用者  
  7.             List<User> list = userService.getAll();  
  8.             response = ServletActionContext.getResponse();  
  9.             // jackson  
  10.             ObjectMapper mapper = new ObjectMapper();  
  11.             // 把取得的使用者list寫入response  
  12.             mapper.writeValue(response.getWriter(), list);  
  13.             return null;  
  14.     }  
  15. }  

 這樣我們在瀏覽器訪問http://yourdomain/security/user/list就可以返回一個包含所有使用者資訊的json陣列

 

hibernate延時載入

因為jsonplugin用的是java的內審機制.hibernate會給被管理的pojo加入一個hibernateLazyInitializer屬性,jsonplugin會把hibernateLazyInitializer也拿出來操作,並讀取裡面一個不能被反射操作的屬性就產生了這個異常.  

 

不過我用的是jackson來轉json,所以想到了用annotation來排除hibernateLazyInitializer 這個屬性

在你的pojo類宣告加上:

 

Java程式碼 複製程式碼
  1. @JsonIgnoreProperties(value={"hibernateLazyInitializer"})  

 

轉換格式設定

近日,使用Jackson轉化JSON物件的時候,顯示的時候,日期始終顯示不正確,輸出的日期是一串數字代表的時間戳,不符合要求,所以想到Jackson應當有方法設定輸出的日期格式。後來一查果然有兩種方式來實現:

1.普通的方式:

預設是轉成timestamps形式的,通過下面方式可以取消timestamps。

Java程式碼 複製程式碼
  1. objectMapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false);  
Java程式碼  收藏程式碼
  1. objectMapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false);  

 這樣將使時間生成使用所謂的use a [ISO-8601 ]-compliant notation, 輸出類似如下格式的時間: "1970-01-01T00:00:00.000+0000".

當然也可以自定義輸出格式:

Java程式碼 複製程式碼
  1. objectMapper.getSerializationConfig().setDateFormat(myDateFormat);  
Java程式碼  收藏程式碼
  1. objectMapper.getSerializationConfig().setDateFormat(myDateFormat);  
Java程式碼 複製程式碼
  1. myDateFormat物件為java.text.DateFormat,具體使用清查java API  
Java程式碼  收藏程式碼
  1. myDateFormat物件為java.text.DateFormat,具體使用清查java API  

2.annotaion的註釋方式:

先定義自己需要的格式,例如:

Java程式碼 複製程式碼
  1. import java.io.IOException;   
  2. import java.text.SimpleDateFormat;   
  3. import java.util.Date;   
  4. import org.codehaus.jackson.JsonGenerator;   
  5. import org.codehaus.jackson.JsonProcessingException;   
  6. import org.codehaus.jackson.map.JsonSerializer;   
  7. import org.codehaus.jackson.map.SerializerProvider;   
  8.   
  9. /**  
  10.  *  java日期物件經過Jackson庫轉換成JSON日期格式化自定義類  
  11.  * @author godfox  
  12.  * @date 2010-5-3  
  13.  */  
  14. public class CustomDateSerializer extends JsonSerializer<Date> {   
  15.   
  16.         @Override  
  17.         public void serialize(Date value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {   
  18.                 SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");   
  19.                 String formattedDate = formatter.format(value);   
  20.                 jgen.writeString(formattedDate);   
  21.         }   
  22. }  
Java程式碼  收藏程式碼
  1. import java.io.IOException;  
  2. import java.text.SimpleDateFormat;  
  3. import java.util.Date;  
  4. import org.codehaus.jackson.JsonGenerator;  
  5. import org.codehaus.jackson.JsonProcessingException;  
  6. import org.codehaus.jackson.map.JsonSerializer;  
  7. import org.codehaus.jackson.map.SerializerProvider;  
  8.   
  9. /** 
  10.  *  java日期物件經過Jackson庫轉換成JSON日期格式化自定義類 
  11.  * @author godfox 
  12.  * @date 2010-5-3 
  13.  */  
  14. public class CustomDateSerializer extends JsonSerializer<Date> {  
  15.   
  16.         @Override  
  17.         public void serialize(Date value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {  
  18.                 SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");  
  19.                 String formattedDate = formatter.format(value);  
  20.                 jgen.writeString(formattedDate);  
  21.         }  
  22. }  

 然後在你的POJO上找到日期的get方法

Java程式碼 複製程式碼
  1. @JsonSerialize(using = CustomDateSerializer.class)   
  2.        public Date getCreateAt() {   
  3.                return createAt;   
  4.        }  
 

相關文章