2012-02-11 8 views
3

不適切な形式のJSON応答を処理しています。すべてのフィールドはStringsとして返されます。残念ながら、私は返品データを支配しません。Stringをdoubleに変換するときのGSONのNumberFormatException

私はGsonを使用して、このようなフィールドを含むJSONオブジェクトを解析しようとしています:

{ 
     [...] 
    "cost": "9.25" 
} 

それは明らかにNumberとして印刷されなければなりません。私はStringNumberまたはdoubleとしてこれを解析しようとすると、私はNumberFormatExceptionが出る:

com.google.gson.JsonSyntaxException: java.lang.NumberFormatException: 
     [...] 
    at com.myapp.android.LauncherActivity$1.onSuccess(LauncherActivity.java:69) 
     [...] 
Caused by: java.lang.NumberFormatException: 
    at org.apache.harmony.luni.util.FloatingPointParser.parseDouble(FloatingPointParser.java:267) 
    at java.lang.Double.parseDouble(Double.java:285) 
    at com.google.gson.stream.JsonReader.nextInt(JsonReader.java:599) 
    at com.google.gson.internal.bind.TypeAdapters$7.read(TypeAdapters.java:228) 
    ... 19 more 

LauncherActivityライン69:

Item item = gson.fromJson(response, Item.class); 

は、だから私はthis similar questionを踏襲し、そのようなTypeAdapterを作成してみました:

そしてGsonBuilderを作成するときに、それを登録:

GsonBuilder builder = new GsonBuilder(); 
builder.registerTypeAdapter(Cost.class, new CostTypeAdapter()); 
Gson gson = builder.create(); 

そして、私のCostクラス:

public class Cost { 
    private Double value; 

    public Cost(Double value) { 
     this.value = value; 
    } 

    public Double getValue() { 
     return value; 
    } 
} 

しかし、私は同じNumberFormatExceptionを取得します。

ここで何が起こっているかに関するアイデアはありますか?この例外は少なくとも私のCostTypeAdapter.deserialize()で捕らえるべきではありませんか?

ご協力いただきありがとうございます。

答えて

2

"Item"クラスを包囲するためにJsonDeserializerを書く必要がありました。

public class ItemDeserializer implements JsonDeserializer<Item> { 

    @Override 
    public Item deserialize(JsonElement json, Type type, 
      JsonDeserializationContext context) throws JsonParseException { 

     JsonObject jobject = (JsonObject) json; 

     return new Item(
        [...], 
       (jobject.has("cost")) ? jobject.get("cost").getAsDouble() : 0.00d 
       ); 
    } 
} 

私の元の問題の解決策を見たいので、手動ですべてのフィールドを解析する必要はありません。

+3

これは、ある種のアノテーション – Gubatron

0

あなたのItemクラスのcostフィールドはdoubleではなくintと宣言されているようです。 doubleに変更すると修正されるはずです。

7

また、GsonBuilderregisterTypeAdapter()を使用して、可能な解析例外をキャッチし、必要な方法で処理することもできます。 null値をFloatを解析し、作るときNumberFormatExceptionをキャッチするため

例:

GsonBuilder gb = new GsonBuilder(); 
    gb.registerTypeAdapter(Float.class, new TypeAdapter<Float>() { 

     @Override 
     public Float read(JsonReader reader) throws IOException { 
      if (reader.peek() == JsonToken.NULL) { 
       reader.nextNull(); 
       return null; 
      } 
      String stringValue = reader.nextString(); 
      try { 
       Float value = Float.valueOf(stringValue); 
       return value; 
      } catch (NumberFormatException e) { 
       return null; 
      } 
     } 

     @Override 
     public void write(JsonWriter writer, Float value) throws IOException { 
      if (value == null) { 
       writer.nullValue(); 
       return; 
      } 
      writer.value(value); 
     } 

    }); 
0

ポールは、私がString秒として保存されている私のJSONで取得数の同様の問題を持っています。どのような私のために働いていますがこのです:

public enum Plan { 
     GUEST_PASS, FREE, PREMIUM; 

     static Plan fromValue(int value) { 
      for (Plan plan : plans) 
       if (value == plan.ordinal()) 
        return plan; 
      throw new IllegalArgumentException("Invalid value for Plan: " + value); 
     } 

     static Plan fromValue(String string) { 
      try { 
       return fromValue(parseInt(string)); 
      } catch (IllegalArgumentException _) { 
       throw new IllegalArgumentException("Invalid value for Plan: " + string); 
      } 
     } 

     private static EnumSet<Plan> plans = EnumSet.allOf(Plan.class); 
    } 

public static class PlanAdapter extends TypeAdapter<Plan> { 
    @Override public void write(JsonWriter json, Plan plan) throws IOException { 
     json.value(Integer.toString(plan.ordinal())); 
    } 

    @Override public Plan read(JsonReader json) throws IOException { 
     return Plan.fromValue(json.nextString()); 
    } 
} 

は、あなたがあなたのケースでは連続的なデータを持っているので、あなたはclassを持つように十分であろうように、私は離散的なデータを持っていたことから、私は列挙型に変換するようです。

関連する問題