2011-09-04 31 views
5

Tôi mã hóa cấu trúc Bản đồ phức tạp với các mảng giá trị kép. Độ chính xác cao là không quan trọng và kích thước đầu ra là, vì vậy tôi đang cố gắng để có được công cụ JSON (Jackson trong trường hợp này) để tuần tự hóa các giá trị kép bằng cách sử dụng một DecimalFormat được cung cấp.jackson - mã hóa json của đôi với độ chính xác được kiểm soát

Sau đây là bức ảnh đẹp nhất của tôi, nhưng điều này không như serializer không chọn bởi các đối tượng mapper để mã hóa các mảng:

class MyTest 
{ 
    public class MyDoubleSerializer extends JsonSerializer<double[]> 
    { 
    public void serialize(double[] value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonProcessingException 
    { 
     for (double d : value) 
     { 
     jgen.writeStartArray(); 
     jgen.writeRaw(df.format(d)); 
     jgen.writeEndArray(); 
     } 
    } 
    } 

    @Test 
    public void test1() throws Exception 
    { 
    ObjectMapper mapper = new ObjectMapper(); 
    SimpleModule module = new SimpleModule("MyModule", new Version(0, 1, 0, "alpha")); 
    module.addSerializer(double[].class, new MyDoubleSerializer()); 
    mapper.registerModule(module); 

    Map<String, Object> data = new HashMap<String, Object>(); 
    double[] doubleList = { 1.1111111111D, (double) (System.currentTimeMillis()) }; 
    data.put("test", doubleList); 
    System.out.print(mapper.writeValueAsString(data)); 
    } 
} 

Đầu ra là:

{ "test" : [1.1111111111,1.315143204964E12}

gì tôi đang tìm kiếm:

{"test": [1.32E12, 1.11E0]}

Mọi ý tưởng?

Ngoài ra, tôi không muốn phải tạo ra một chuỗi và ghi là thô - là có tôi có thể nuôi một StringBuffer vào DecimalFormat để làm điều này?

Cảm ơn

Trả lời

4

Được quản lý để giải quyết vấn đề này, bằng cách mượn từ bộ nối tiếp tích hợp cho Double.

Đó là một chút hack, vì writeRaw() không quan tâm đến ngữ cảnh và không viết dấu phẩy giữa các thành viên mảng, vì vậy tôi đang truyền nhà văn Json và gọi phương thức writeValue() của nó để xử lý điều này.

Kỳ lạ, điều này không làm việc trên ví dụ trong câu hỏi (một lần nữa không được gọi để tuần tự hóa các đôi), nhưng làm việc trên đối tượng thế giới thực của tôi phức tạp hơn.

Thưởng thức ...

public class JacksonDoubleArrayTest 
{ 
    private DecimalFormat df = new DecimalFormat("0.##E0"); 

    public class MyDoubleSerializer extends org.codehaus.jackson.map.ser.ScalarSerializerBase<Double> 
    { 
     protected MyDoubleSerializer() 
     { 
      super(Double.class); 
     } 

     @Override 
     public final void serializeWithType(Double value, JsonGenerator jgen, SerializerProvider provider, TypeSerializer typeSer) throws IOException, 
       JsonGenerationException 
     { 
      serialize(value, jgen, provider); 
     } 

     @Override 
     public void serialize(Double value, JsonGenerator jgen, SerializerProvider provider) throws IOException, JsonGenerationException 
     { 
      if (Double.isNaN(value) || Double.isInfinite(value)) 
      { 
       jgen.writeNumber(0); // For lack of a better alternative in JSON 
       return; 
      } 

      String x = df.format(value); 
      if (x.endsWith("E0")) 
      { 
       x = x.substring(0, x.length() - 2); 
      } 
      else if (x.endsWith("E1") && x.length() == 6) 
      { 
       x = "" + x.charAt(0) + x.charAt(2) + '.' + x.charAt(3); 
      } 
      JsonWriteContext ctx = (JsonWriteContext)jgen.getOutputContext(); 
      ctx.writeValue(); 
      if (jgen.getOutputContext().getCurrentIndex() > 0) 
      { 
       x = "," + x; 
      } 
      jgen.writeRaw(x); 
     } 

     @Override 
     public JsonNode getSchema(SerializerProvider provider, Type typeHint) 
     { 
      return createSchemaNode("number", true); 
     } 
    } 

    @SuppressWarnings("unchecked") 
    private static Map<String, Object> load() throws JsonParseException, JsonMappingException, IOException 
    { 
     ObjectMapper loader = new ObjectMapper(); 
     return (Map<String, Object>)loader.readValue(new File("x.json"), Map.class); 
    } 

    @Test 
    public void test1() throws JsonGenerationException, JsonMappingException, IOException 
    { 
     ObjectMapper mapper = new ObjectMapper(); 
     SimpleModule module = new SimpleModule("StatsModule", new Version(0, 1, 0, "alpha")); 
     module.addSerializer(Double.class, new MyDoubleSerializer()); 
     mapper.registerModule(module); 
     String out = mapper.writeValueAsString(load()); 
     // System.out.println(out.length()); 
    } 
} 
Các vấn đề liên quan