2012-07-12 20 views
39

Tôi có một số Map<String,Foo> foosMap mà tôi muốn tuần tự hóa thông qua Jackson. Bây giờ tôi muốn theo hai cài đặt trong quá trình tuần tự hóa:Làm thế nào để ngăn chặn các giá trị null bên trong một Bản đồ và các trường rỗng bên trong một bean từ việc được tuần tự hóa qua Jackson

  1. Bản đồ có thể có nhiều giá trị null và khóa rỗng và tôi không muốn null được sắp xếp theo thứ tự.
  2. Đối với tất cả những Foos đang được sắp xếp theo thứ tự, tôi không muốn tuần tự hóa các đối tượng null được tham chiếu bên trong Foo.

Cách tốt nhất để đạt được điều này là gì? Tôi đang sử dụng jackson-core1.9 và jackson-mapper1.9 lọ trong dự án của tôi.

+0

Có thể trùng lặp, vui lòng kiểm tra liên kết này: http://stackoverflow.com/questions/3140563/how-to-avoi d-null-values-serialization-in-hashmap – dbf

+0

Bản đồ có thể có tối thiểu một khóa rỗng – amicngh

+0

@dbf không hoàn toàn. vui lòng xem lại tiêu đề câu hỏi đã chỉnh sửa. – Inquisitive

Trả lời

91

Nếu hợp lý để thay đổi cấu trúc dữ liệu ban đầu được nối tiếp để đại diện tốt hơn giá trị thực tế muốn được tuần tự hóa, đó có thể là cách tiếp cận phù hợp, điều này có thể làm giảm số lượng cấu hình Jackson cần thiết. Ví dụ: chỉ cần xóa các mục nhập chính null, nếu có thể, trước khi gọi cho Jackson. Điều đó nói rằng ...


Để ngăn chặn serializing Map mục với giá trị null:

Trước Jackson 2,9

bạn vẫn có thể tận dụng WRITE_NULL_MAP_VALUES, nhưng lưu ý rằng nó chuyển đến SerializationFeature:

mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false); 

Vì Jackson 2,9

Các WRITE_NULL_MAP_VALUES bị phản đối, bạn có thể sử dụng tương đương dưới đây:

mapper.setDefaultPropertyInclusion(
    JsonInclude.Value.construct(Include.ALWAYS, Include.NON_NULL)) 

Để ngăn chặn serializing tính với các giá trị null, bạn có thể configure the ObjectMapper directly, hoặc tận dụng các @JsonInclude chú thích:

mapper.setSerializationInclusion(Include.NON_NULL); 

hoặc:

@JsonInclude(Include.NON_NULL) 
class Foo 
{ 
    public String bar; 

    Foo(String bar) 
    { 
    this.bar = bar; 
    } 
} 

Để xử lý null Map khóa, một số tùy chỉnh tuần tự là cần thiết, như tôi hiểu rõ nhất.

Một cách tiếp cận đơn giản để serialize null phím như chuỗi rỗng (bao gồm cả ví dụ hoàn chỉnh của hai cấu hình đề cập ở trên):

import java.io.IOException; 
import java.util.HashMap; 
import java.util.Map; 

import com.fasterxml.jackson.annotation.JsonInclude.Include; 
import com.fasterxml.jackson.core.JsonGenerator; 
import com.fasterxml.jackson.core.JsonProcessingException; 
import com.fasterxml.jackson.databind.JsonSerializer; 
import com.fasterxml.jackson.databind.ObjectMapper; 
import com.fasterxml.jackson.databind.SerializationFeature; 
import com.fasterxml.jackson.databind.SerializerProvider; 

public class JacksonFoo 
{ 
    public static void main(String[] args) throws Exception 
    { 
    Map<String, Foo> foos = new HashMap<String, Foo>(); 
    foos.put("foo1", new Foo("foo1")); 
    foos.put("foo2", new Foo(null)); 
    foos.put("foo3", null); 
    foos.put(null, new Foo("foo4")); 

    // System.out.println(new ObjectMapper().writeValueAsString(foos)); 
    // Exception: Null key for a Map not allowed in JSON (use a converting NullKeySerializer?) 

    ObjectMapper mapper = new ObjectMapper(); 
    mapper.configure(SerializationFeature.WRITE_NULL_MAP_VALUES, false); 
    mapper.setSerializationInclusion(Include.NON_NULL); 
    mapper.getSerializerProvider().setNullKeySerializer(new MyNullKeySerializer()); 
    System.out.println(mapper.writeValueAsString(foos)); 
    // output: 
    // {"":{"bar":"foo4"},"foo2":{},"foo1":{"bar":"foo1"}} 
    } 
} 

class MyNullKeySerializer extends JsonSerializer<Object> 
{ 
    @Override 
    public void serialize(Object nullKey, JsonGenerator jsonGenerator, SerializerProvider unused) 
     throws IOException, JsonProcessingException 
    { 
    jsonGenerator.writeFieldName(""); 
    } 
} 

class Foo 
{ 
    public String bar; 

    Foo(String bar) 
    { 
    this.bar = bar; 
    } 
} 

Để ngăn chặn serializing Map mục với null phím, chế biến serialization thêm tùy chỉnh sẽ là cần thiết.

+2

Chỉ cần báo trước các hướng dẫn này là Jackson 2.0 cụ thể ('com.fasterxml' vs' org.codehaus'). –

+0

@ProgrammerBruce - Có thể ngăn chặn tuần tự hóa trường rỗng cho một lớp cụ thể trong trình ánh xạ đối tượng không? ví dụ: Sử dụng cùng trình ánh xạ đối tượng để tuần tự hóa lớp A và B, nhưng chỉ các trường rỗng trong lớp B bị bỏ qua. – ThatGuyGrant

+0

@ProgrammerBurce - khi jackson đã nâng cấp lên 2.9, WRITE_NULL_MAP_VALUES không được chấp nhận. Bạn có biết có cách nào khác để làm tương tự không? –

18

Đối với phiên bản Jackson < 2.0 sử dụng chú thích này trên lớp được đăng:

@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL) 
+1

FYI, điều này không được chấp nhận, câu trả lời được chấp nhận ở trên có chú thích mới nhất: @JsonInclude (Bao gồm.NON_NULL) – Amber

+0

Lưu ý rằng chú thích JsonInclude không có sẵn nếu bạn đang sử dụng Jackson 1.9.x, trong trường hợp đó bạn sẽ phải sử dụng chú thích JsonSerialize. –

+0

Tôi xác nhận với Jackson 1.9.x @JsonInclude (Include.NON_NULL) không hoạt động. Tôi đang nhập gói này: org.codehaus.jackson.map – Emanuele

3

trả lời có vẻ là một ít tuổi, Những gì tôi đã làm là sử dụng ánh xạ này để chuyển đổi một MAP

 ObjectMapper mapper = new ObjectMapper().configure(SerializationConfig.Feature.WRITE_NULL_MAP_VALUES, false); 

một đơn giản:

  Map<String, Object> user = new HashMap<String,Object>(); 
      user.put("id", teklif.getAccount().getId()); 
      user.put("fname", teklif.getAccount().getFname()); 
      user.put("lname", teklif.getAccount().getLname()); 
      user.put("email", teklif.getAccount().getEmail()); 
      user.put("test", null); 

Sử dụng nó như thế này ví dụ:

 String json = mapper.writeValueAsString(user); 
0

giải pháp của tôi, hy vọng giúp đỡ
tùy chỉnh ObjectMapper và cấu hình để mùa xuân xml (đăng ký conveters nhắn)

public class PyResponseConfigObjectMapper extends ObjectMapper { 
public PyResponseConfigObjectMapper() { 
    disable(SerializationFeature.WRITE_NULL_MAP_VALUES); //map no_null 
    setSerializationInclusion(JsonInclude.Include.NON_NULL); // bean no_null 
} 

}

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