2011-09-04 3 views
5

Karmaşık bir Harita yapısını çift değer dizileri ile kodlarım. Yüksek hassasiyet önemli değil ve çıktı boyutu, bu yüzden JSON aracını (bu durumda Jackson) sağlanan bir DecimalFormat kullanarak çift değerleri serileştirmeye çalışıyorum.jackson - kontrollü hassaslıkla çiftlerin json kodlaması

aşağıdaki benim en iyi atış, ama serileştirici dizisi kodlamak için nesne haritacının alınmadıkça Bu başarısız:

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)); 
    } 
} 

çıktısı:

{ "test" : [1.1111111111,1.315143204964E12}

aradığım ne:

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

Herhangi bir fikir? Ayrıca

, ben sevmiyorum bir String ve yazma üretmek için ham olarak söz konusu olan - bir orada bunu yapmak DecimalFormat içine içine bir StringBuffer yem olabilir?

Teşekkür

cevap

4

borçlanmayla, bu sorunu çözmek için Yönetilen yerleşik Çift için serileştiriciden.

Biraz kesinti var, çünkü writeRaw() bağlamla ilgilenmiyor ve dizi üyeleri arasında virgül yazmıyor, bu yüzden Json yazıcısını çalıştırıyorum ve onun writeValue() yöntemini çağırıyorum. bu.

Gariptir ki, bu (yine bu çiftler seri çağrısında almaz) Söz konusu örnekte çalışmıyor, ancak daha karmaşıktır benim gerçek dünya nesne üzerinde çalışır.

... Enjoy

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()); 
    } 
}