2011-08-12 32 views
8

Tôi biết rằng có nhiều cách để yêu cầu JacksonJson bỏ qua các thuộc tính trong khi hiển thị nhưng tất cả đều là tĩnh. (JasonIgnore, các lớp MixIn, ..).Tự động bỏ qua các thuộc tính với JacksonJson

Đây là kịch bản của tôi. Một đối tượng miền có thể thực hiện một giao diện gọi là FilteredDomain đến cho phép nó được lọc động. Giao diện đơn giản và chỉ hiển thị một phương thức "getIgnoreProperties". (Một danh sách các thuộc tính để bỏ qua).

Sau đó, tôi đăng ký Trình nối tiếp tùy chỉnh liên kết với đối tượng FilteredDomain. Mã trông giống như sau:

private class FilteredDomainSerializer extends JsonSerializer<FilteredDomain> { 

    public void serialize(FilteredDomain arg, JsonGenerator jgen, 
      SerializerProvider provder) throws IOException, 
      JsonProcessingException { 

     final BeanWrapper wrapper = PropertyAccessorFactory.forBeanPropertyAccess(arg); 

     for (PropertyDescriptor pd : wrapper.getPropertyDescriptors()) { 
      final String name = pd.getName(); 

      if (arg.getIgnoreProperties().containsKey(name)) 
       continue; 

      final Object value = wrapper.getPropertyValue(name); 

      jgen.writeObjectField(name, value); 
     } 
    } 
} 

Trước tiên, tôi thực sự không thích mà tôi cần phải sử dụng các wrapper Xuân Bean để có được một danh sách tất cả các thuộc tính và lặp qua chúng (Phải có một cách để làm điều này là jackson json).

Thứ hai, Mã vẫn không hoạt động. Tôi nhận được lỗi:

org.codehaus.jackson.JsonGenerationException: Không thể ghi tên trường, mong đợi một giá trị tại org.codehaus.jackson.impl.JsonGeneratorBase._reportError (JsonGeneratorBase.java:480) tại org .codehaus.jackson.impl.Utf8Generator.writeFieldName (Utf8Generator.java:270) tại org.codehaus.jackson.JsonGenerator.writeObjectField (JsonGenerator.java:1088) tại com.rootmusic.util.SystemJsonObjectMapper $ ValueObjectSerializer.serialize (SystemJsonObjectMapper .java: 65) tại com.rootmusic.util.SystemJsonObjectMapper $ ValueObjectSerializer.serialize (SystemJsonObjectMapper.java:1) tại org.codehaus.jackson.map.ser.ContainerSerializers $ IndexedListSerializer.serializeContents (ContainerSe rializers.java:304) tại org.codehaus.jackson.map.ser.ContainerSerializers $ IndexedListSerializer.serializeContents (ContainerSerializers.java:254) tại org.codehaus.jackson.map.ser.ContainerSerializers $ AsArraySerializer.serialize (ContainerSerializers. java: 142) tại org.codehaus.jackson.map.ser.MapSerializer.serializeFields (MapSerializer.java:287) tại org.codehaus.jackson.map.ser.MapSerializer.serialize (MapSerializer.java:212) tại org.codehaus.jackson.map.ser.MapSerializer.serialize (MapSerializer.java:23) tại org.codehaus.jackson.map.ser.StdSerializerProvider._serializeValue (StdSerializerProvider.java:606) tại org.codehaus.jackson. map.ser.StdSerializerProvider.serializeValue (StdSerializerProvider.java:280)

Trả lời

8

Lỗi xuất phát từ thực tế là bạn không viết START_OBJECT/END_OBJECT xung quanh cặp tên/giá trị trường, do đó cần phải dễ khắc phục.

Để lọc động hơn, bạn có thể đọc this blog entry bao gồm các phương pháp chuẩn. @JsonView hoạt động nếu bạn có bộ định nghĩa tĩnh (một trong số đó bạn có thể tự động chọn trên cơ sở từng tuần tự), nhưng nếu bạn muốn có thêm hệ thống động, @JsonFilter là cách để đi.

Ngoài ra, một cách tương đối đơn giản sẽ là lần đầu tiên "chuyển đổi" POJO của bạn thành một bản đồ:

Bản đồ props = objectMapper.convertValue (POJO, Map.class);

(tương tự như serializing nó như JSON, ngoại trừ kết quả đó là một bản đồ mà sẽ trả lại như JSON)

và sau đó chọn lọc cắt Map, và serialize đó như JSON.Hoặc, nếu bạn thích, bạn có thể sử dụng JsonNode ("mô hình cây") làm điều trung gian để sửa đổi và sau đó tuần tự hóa.

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