spring學習筆記---Jackson的使用和定製

 

前言:
  JAVA老是把實體對象(數據庫/Nosql等)轉換爲POJO對象再處理, 雖然有各種框架予以強力支持. 但實體對象和POJO, 因爲"飲食習慣", "民族特點", "地域區別"等等差別, 須要有些定製需求, 使得可以完美的映射. 這個性化定製需求, 包括名稱/時間格式/字段過濾等等約定.
  springmvc的學習筆記系列:
  • idea建立springmvc項目
  • 面向移動端支持REST API
  本文講講述如何把pojo對象轉化爲約定好的json數據格式. 權當筆記.html

疑問篇:
  springmvc在使用註解@ResponseBody返回一個POJO對象時, 其內部會藉助Jackson來完成POJO轉化爲JSON的工做.
  好比對於以下的POJO類: java

public class Message {

  private String userId; // 用戶id

  private String message; // 消息實體

  private Date timestamp; // 時間信息, yyyy-MM-dd HH:mm:ss

  private String extra; // 額外附帶信息

}

  其最終講轉換爲以下的json格式:
  
  若是開發者須要以下需求:
  1). json實體的key命名規則, 全小寫化, 不一樣單詞以"_"字符鏈接.
  2). 返回時間字段, 需知足"yyyy-MM-dd HH:mm:ss"格式
  3). 省略掉extra字段
  因而可知咱們的最終目標是: spring

{"user_id":"1001","message":"message","timestamp":"2015-08-31 12:16:30"}

解決篇:
  • 重命名
  jackson對重命名的處理, 引入註解JsonProperty來實現. 其對單個屬性配置有效. sql

@JsonProperty(value="user_id")
private String userId; // 用戶id

  注: value屬性設置爲用戶想要的命名便可.
  固然還有另外一種方式註解方式, 是JsonNaming, 其修飾於POJO類上. 用於對全部屬性, 進行統一的命名轉換.數據庫

@JsonNaming(PropertyNamingStrategy.LowerCaseWithUnderscoresStrategy.class)
public class Message {
  ...
}

  注: PropertyNamingStrategy就很是漂亮地把全部的類屬性名稱都轉換爲小寫, 同時單詞(駝峯命令法)之間使用'_'字符來分割.
  自定義的Strategy類, 須要實現以下抽象類:json

public abstract class PropertyNamingStrategy implements Serializable {
  public abstract static class PropertyNamingStrategyBase extends PropertyNamingStrategy {
    public abstract String translate(String var1);
  }
}

  • 字段可見性
  過濾某些字段屬性, jackson引入了註解JsonIgnore. 其對單個屬性生效.微信

@JsonIgnore
private String extra; // 額外附帶信息

  還有另一種方式, 是採用JsonIgnoreProperties, 其修飾POJO類, 指定一組須要忽略的字段.mvc

// *) 字典{}內是property name列表
@JsonIgnoreProperties({"extra", "extra1", "extra2"})
public class Message {
  ...
}

  • 自定義序列化/反序列化
  jackson採用@JsonSerialize@JsonDeserialize來實現自定義序列化/反序列化的實現. 如以前的時間字段做爲例子.
  定義時間序列化的實現類.框架

public class Message {

  @JsonSerialize(using=DemoDateSerializer.class)
  @JsonDeserialize(using=DemoDateDeserializer.class)
  private Date timestamp; // 時間信息, yyyy-MM-dd HH:mm:ss

}

// *) JSON的序列化類
class DemoDateSerializer extends JsonSerializer<Date> {
  @Override
  public void serialize(Date value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException {
    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    jgen.writeString(dateFormat.format(value));
  }
}

// *) JSON的反序列化類
class DemoDateDeserializer extends JsonDeserializer<Date> {
  @Override
  public Date deserialize(JsonParser jp, DeserializationContext dctx) throws IOException, JsonProcessingException {
    DateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    try {
      return dateFormat.parse(jp.getValueAsString());
    } catch (ParseException e) {
      e.printStackTrace();
    } finally {
    }
    return null;
  }
}

  除了常規的時間格式轉換, 還能正則提取等功能. 序列化和反序列化的自定義, 使得Jackson更加的強大. 猶如hive中的UDF函數.ide

實驗效果:
  最終的定義的類修改以下:

public class Message {

  @JsonProperty(value="user_id")
  private String userId; // 用戶id

  private String message; // 消息實體

  @JsonSerialize(using=DemoDateSerializer.class)
  @JsonDeserialize(using=DemoDateDeserializer.class)
  private Date timestamp; // 時間信息, yyyy-MM-dd HH:mm:ss

  @JsonIgnore
  private String extra; // 額外附帶信息

}

  最終的效果如圖所示:
  
  與最初指望的效果保持一致, 值得小小慶祝一下.

總結:
  jackson還有不少高階的用法, 好比破除循環引用的處理機制, 多類別的處理等等. 這邊暫時忽略, 本文參考了博文"jackson annotations註解詳解" , 深表敬意和感謝. 

寫在最後:
  
若是你以爲這篇文章對你有幫助, 請小小打賞下. 其實我想試試, 看看寫博客可否給本身帶來一點小小的收益. 不管多少, 都是對樓主一種由衷的確定.

   

公衆號&遊戲站點:
  我的微信公衆號: 木目的H5遊戲世界
  

相關文章
相關標籤/搜索