2011-10-27 31 views
7

Tôi có một lớp học có hơn một chục tài sản. Đối với hầu hết các thuộc tính của kiểu nguyên thủy, tôi hy vọng sẽ sử dụng BeanSerializer và BeanDeserializer mặc định hoặc bất cứ điều gì để giảm bớt mã cồng kềnh mà tôi cần phải viết. Đối với các thuộc tính khác của các kiểu mảng tùy chỉnh và mảng, tôi muốn làm một số trình tự/bộ chỉnh sửa tùy chỉnh. Lưu ý rằng tôi không thể thay đổi chuỗi JSON cơ bản. Nhưng tôi có toàn quyền truy cập vào mã Android. Tôi đang sử dụng Jackson 1.7.9/Ektorp 1.1.1.Làm thế nào để viết serializer tùy chỉnh và deserializer trong Jackson?

tôi có nên phân lớp BeanDeserializer không? Tôi đang gặp rắc rối với điều đó. Nó hy vọng một hàm tạo mặc định không có tham số nhưng tôi không biết cách gọi hàm tạo siêu.

class MyType{ 
    // a dozen properties with primitive types String, Int, BigDecimal 
    public Stirng getName(); 
    public void setName(String name); 

    // properties that require custom deserializer/serializer 
    public CustomType getCustom(); 
    public void setCustom(CustomType ct); 
} 

class MyDeserializer extends BeanDeserialzer{ 
    // an exception is throw if I don't have default constructor. 
    // But BeanDeserializer doesn't have a default constructor 
    // It has the below constructor that I don't know how to fill in the parameters 
    public MyDeserializer(AnnotatedClass forClass, JavaType type, 
     BeanProperty property, CreatorContainer creators, 
     BeanPropertyMap properties, 
     Map<String, SettableBeanProperty> backRefs, 
     HashSet<String> ignorableProps, boolean ignoreAllUnknown, 
     SettableAnyProperty anySetter) { 
    super(forClass, type, property, creators, properties, backRefs, ignorableProps, 
      ignoreAllUnknown, anySetter); 
} 
    @Override 
    public Object deserialize(JsonParser jp, DeserializationContext dc, Object bean) 
     throws IOException, JsonProcessingException { 
    super.deserialize(jp, dc, bean); 
     MyType c = (MyType)bean;   

      ObjectMapper mapper = new ObjectMapper(); 

      JsonNode rootNode = mapper.readValue(jp, JsonNode.class); 
      // Use tree model to construct custom 
      // Is it inefficient because it needs a second pass to the JSON string to construct the tree? 
      c.setCustom(custom); 
      return c; 
} 
} 

Tôi đã tìm kiếm trên Google nhưng không thể tìm thấy bất kỳ ví dụ/hướng dẫn hữu ích nào. Nếu bất cứ ai có thể gửi cho tôi một số ví dụ làm việc sẽ tuyệt vời! Cảm ơn!

Trả lời

4

Để phụ lớp BeanSerializer/-Deserializer, bạn nên sử dụng phiên bản mới hơn của Jackson, vì khu vực này đã được cải thiện với sự hỗ trợ rõ ràng thông qua BeanSerializerModifier và BeanDeserializerModifier, có thể thay đổi cấu hình các cá thể.

Nhưng chỉ để chắc chắn, bạn cũng có thể chỉ định tùy chỉnh serializer/deserializer chỉ được sử dụng trên tài sản cá nhân, như vậy:

class Foo { 
    @JsonSerialize(using=MySerializer.class) 
    public OddType getValue(); 
} 
+0

Cảm ơn ý tưởng! Tôi sẽ thử xem nó có hiệu quả không. Tôi đang sử dụng Ektorp cho Android và họ đề xuất 1.1.1 nên đó là lý do tôi sử dụng Jackson 1.7.9. Nhưng nó có thể hoạt động nếu tôi nâng cấp. –

+0

phiên bản cao nhất tôi có thể đi là 1.8.5. Bất kì lời đề nghị nào? Tôi sẽ thử ý tưởng JsonSerializer của bạn trên OddType. –

+0

1.8 có khả năng ghi đè tốt hơn 1.7 nên có thể thực sự hoạt động. Sử dụng BeanSerializerModifier bạn không thực sự phải ghi đè lên BeanSerializer, nhưng cũng có thể tạo các cá thể tùy chỉnh, nhưng trì hoãn các đạo cụ khác cho các thiết lập mặc định. Ngoài ra, serializers tùy chỉnh của bạn có thể tra cứu những cái mặc định trong phương thức 'resolve()' (nếu bạn thực hiện ResolvableSerializer, tương tự như cách BeanSerializer làm). Lý tưởng nhất là bạn nên tránh phân lớp BeanSerializers nếu có thể, chỉ để đơn giản; nhưng nếu bạn cần phải phụ lớp, đó là một kỹ thuật được hỗ trợ quá. – StaxMan

Các vấn đề liên quan