2016-11-19 18 views
8

Tôi tự hỏi làm thế nào để Firebase serialize/deserialize POJO đối tượng đến/từ json, nó sử dụng Jackson hoặc Gson hoặc bất kỳ thư viện tương tự khác.
Tôi gặp sự cố về quy ước đặt tên với Firebase. Mô hình của tôi một số như thế này:Quy ước đặt tên với tuần tự hóa/deserialization Firebase?

class Data { 
    private String someFieldName; 
    private String anotherFieldName; 
    public Data() {} 
    public void setSomeFieldName(String) {...} 
    public String getSomeFieldName(String) {...} 
    public void setAnotherFieldName(String) {...} 
    public String getAnotherFieldName() {...} 
} 

Và kết quả mong đợi trong căn cứ hỏa lực nên là:

{ 
    "some_field_name" : "...", 
    "another_field_name" : "..." 
} 

với Gson tôi có thể sử dụng FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES cho mục đích của tôi, như trong Gson doc:

Dưới đây là một vài ví dụ về biểu mẫu "Tên trường Java" ---> "Tên trường JSON":

  • someFieldName ---> some_field_name
  • _someFieldName ---> _some_field_name

  • aStringField ---> a_string_field

  • aURL ---> a_u_r_l

Làm cách nào để chuyển đổi đối tượng POJO của tôi thành "Giá trị Firebase" với tên cụ thể ing quy ước và ngược lại, hoặc có bất kỳ cách nào để tùy chỉnh quá trình serialize/deserialize?

Cảm ơn!

+1

Sử dụng '@SerializedName ("whateverCamelCase_or_underscore_field_name") ' –

Trả lời

13

Khi đọc những dữ liệu trở lại từ cơ sở dữ liệu căn cứ hỏa lực bạn có thể sử dụng @PropertyName chú thích để đánh dấu một trường để được đổi tên khi bị serialized/deserialized, như vậy:

@IgnoreExtraProperties 
class Data { 
    @PropertyName("some_field_name") 
    public String someFieldName 
    @PropertyName("another_field_name") 
    private String anotherFieldName; 
    public Data() {} 
} 

Hãy chắc chắn rằng lĩnh vực của bạn là công khai và không riêng tư hoặc chú thích khác sẽ không hoạt động (tôi cũng tin rằng Firebase sử dụng Jackson để xử lý ánh xạ đối tượng dưới mui xe, nhưng không nghĩ bạn thực sự có thể tùy chỉnh CÁCH sử dụng nó).

+0

Đây không phải là GSON cũng Jackson, làm bạn có liên kết tài liệu @crymson? – ericn

+0

@ericn bạn đúng rằng nó không phải là. Tôi nói Jackson bởi vì các chú thích trông khá giống nhau nhưng tôi thực sự không thể biết chắc chắn, mặc dù một số dữ liệu trong tài liệu tham khảo này đưa ra một đầu mối https://www.firebase.com/docs/java-api/javadoc/com/firebase /client/GenericTypeIndicator.html (lưu ý tham chiếu đến Jackson ở trên cùng) – crymson

+0

Cảm ơn, Nó giúp tôi tiết kiệm rất nhiều thời gian! –

4

Cá nhân tôi muốn giữ kiểm soát rõ ràng quá trình tuần tự hóa/deserialization và không dựa vào khung và/hoặc chú thích cụ thể.

lớp dữ liệu của bạn có thể chỉ cần điều chỉnh như thế này:

class Data { 
    private String someFieldName; 
    private String anotherFieldName; 
    public Data() {} 
    public Data(Map<String, Object> map) { 
     someFieldName = (String) map.get("some_field_name") ; 
     anotherFieldName = (String) map.get("another_field_name") ; 
    } 

    public Map<String, Object> toMap() { 
     Map<String, Object> map = new HashMap<>(); 
     map.put("some_field_name", someFieldName); 
     map.put("another_field_name", anotherFieldName); 
     return map ; 
    } 
} 

Đối với văn bản giá trị cho căn cứ hỏa lực, chỉ cần làm:

dbref.setValue(data.toMap()); 

Để đọc:

Map<String, Object> map = (Map<String, Object>) dataSnapshot.getValue(); 
data = new Data(map); 

Họ là một số lợi thế với giải pháp này:

  • Không giả định được thực hiện trên khuôn khổ json tiềm ẩn
  • Không cần phải sử dụng các chú thích
  • Bạn thậm chí có thể tiếp tục tách bạn Object mô hình từ mô hình Json của bạn bằng cách externalizing các phương pháp toMap() và xây dựng một DataMapper (đoạn dưới đây)

public static Data fromMap(Map<String, Object> map) { 
    String someFieldName = (String) map.get("some_field_name") ; 
    String anotherFieldName = (String) map.get("another_field_name") ; 
    return new Data(someFieldName, anotherFieldName); 
} 

public static Map<String, Object> toMap(Data data) { 
    Map<String, Object> map = new HashMap<>(); 
    map.put("some_field_name", data.getSomeFieldName()); 
    map.put("another_field_name", data.getAnotherFieldName()); 
    return map ; 
} 
+0

Tôi có thể đánh giá cao một cách tiếp cận thay thế hoặc các yêu cầu phức tạp hơn, nhưng việc loại bỏ chú thích là quá mức cần thiết. Chú thích là khá mạnh mẽ và được thiết kế đặc biệt để tránh thêm mã hóa boilerplate như bạn đã viết trong giải pháp của bạn. @PropertyName ("your_name") cung cấp cho bạn cả bản đồ đọc và viết và có thể dễ dàng duy trì trong phần lớn các trường hợp. – giulio

+0

@giulio Tôi đồng ý với bạn ... Không cần sử dụng chú thích không phải là một lợi thế thực sự. Nếu chúng là những chú thích độc lập với khung công tác (Không ràng buộc với Jackson) và được Jackson hoặc Firebase công nhận, tôi sẽ sử dụng chúng. – Benoit