jackson 自定義序列化

NO IMAGE

對於一直用gson的人來說,如果單獨用jackson,真是麻煩了,但還是得小結下了: 
先來看下如何自定義把某個物件序列化為json: 

先是物件: 

Java程式碼  收藏程式碼
  1. public class User {  
  2.     public int id;  
  3.     public String name;  
  4. }  
  5. public class Item {  
  6.     public int id;  
  7.     public String itemName;  
  8.     public User owner;  
  9. }  

   JACKSON一般的使用很容易,如; 
Item myItem = new Item(1, “theItem”, new User(2, “theUser”)); 
String serialized = new ObjectMapper().writeValueAsString(myItem); 
  結果為: 

    “id”: 1, 
    “itemName”: “theItem”, 
    “owner”: { 
        “id”: 2, 
        “name”: “theUser” 
    } 

  如果要輸出為如下的樣子,比如; 

    “id”: 25, 
    “itemName”: “FEDUfRgS”, 
    “owner”: 15 

  則要自定義了,要繼承JsonSerializer類,如下: 
 

Java程式碼  收藏程式碼
  1. public class ItemSerializer extends JsonSerializer<Item> {  
  2.     @Override  
  3.     public void serialize(Item value, JsonGenerator jgen, SerializerProvider provider)   
  4.       throws IOException, JsonProcessingException {  
  5.         jgen.writeStartObject();  
  6.         jgen.writeNumberField(“id”, value.id);  
  7.         jgen.writeStringField(“itemName”, value.itemName);  
  8.         jgen.writeNumberField(“owner”, value.owner.id);  
  9.         jgen.writeEndObject();  
  10.     }  
  11. }  

  然後 

Java程式碼  收藏程式碼
  1. Item myItem = new Item(1, “theItem”, new User(2, “theUser”));  
  2. ObjectMapper mapper = new ObjectMapper();  
  3.    
  4. SimpleModule module = new SimpleModule();  
  5. module.addSerializer(Item.class, new ItemSerializer());  
  6. mapper.registerModule(module);  
  7.    
  8. String serialized = mapper.writeValueAsString(myItem);  

    看,相當複雜,然後看有無辦法簡單點,其實是有的哦;方法為: 

Java程式碼  收藏程式碼
  1. @JsonSerialize(using = ItemSerializer.class)  
  2. public class Item {  
  3.     …  
  4. }  

  就是使用註解@JsonSerialize,然後: 
  

Java程式碼  收藏程式碼
  1. Item myItem = new Item(1, “theItem”, new User(2, “theUser”));  
  2. String serialized = new ObjectMapper().writeValueAsString(myItem);  

  接下來看如何反序列化了, 
同樣,要反序列化的兩個pojo為: 
 

Java程式碼  收藏程式碼
  1. public class User {  
  2.     public int id;  
  3.     public String name;  
  4. }  
  5. public class Item {  
  6.     public int id;  
  7.     public String itemName;  
  8.     public User owner;  
  9. }  

   反序列化程式碼為: 
Item itemWithOwner = new ObjectMapper().readValue(json, Item.class); 
  
如果要自定義反序列化,比如要反序列化的JSON為; 

    “id”: 1, 
    “itemName”: “theItem”, 
    “owner”: 2 

  則上面這樣會報錯: 
com.fasterxml.jackson.databind.exc.UnrecognizedPropertyException: 
Unrecognized field “createdBy” (class org.baeldung.jackson.dtos.Item), 
not marked as ignorable (3 known properties: “id”, “owner”, “itemName”]) 
at [Source: [email protected]; line: 1, column: 43] 
(through reference chain: org.baeldung.jackson.dtos.Item[“createdBy”]) 
  
程式碼: 
  

Java程式碼  收藏程式碼
  1. public class ItemDeserializer extends JsonDeserializer<Item> {  
  2.    
  3.     @Override  
  4.     public Item deserialize(JsonParser jp, DeserializationContext ctxt)   
  5.       throws IOException, JsonProcessingException {  
  6.         JsonNode node = jp.getCodec().readTree(jp);  
  7.         int id = (Integer) ((IntNode) node.get(“id”)).numberValue();  
  8.         String itemName = node.get(“itemName”).asText();  
  9.         int userId = (Integer) ((IntNode) node.get(“id”)).numberValue();  
  10.    
  11.         return new Item(id, itemName, new User(userId, null));  
  12.     }  
  13. }  
  14.   
  15. ObjectMapper mapper = new ObjectMapper();  
  16. SimpleModule module = new SimpleModule();  
  17. module.addDeserializer(Item.class, new ItemDeserializer());  
  18. mapper.registerModule(module);  
  19.    
  20. Item readValue = mapper.readValue(json, Item.class);  

   也可以用註解: 
@JsonDeserialize(using = ItemDeserializer.class) 
public class Item { 
    …