Json String contain integer value , while deserialize to HashMap, Integer convert into double values

可紊 提交于 2019-12-11 12:58:31

问题


public static void main(String[] args) {

    Gson g = new GsonBuilder()
            .setPrettyPrinting()
            .enableComplexMapKeySerialization()
            .serializeSpecialFloatingPointValues()
            .setLongSerializationPolicy(LongSerializationPolicy.DEFAULT)
            .setPrettyPrinting()
            //.registerTypeAdapter(HashMap.class, new HashMapDeserializer())
            .create();

    HashMap<Object, Object> h = new HashMap<Object, Object>();
    h.put("num1", 10);
    h.put("num2", 20);
    h.put("num3", 20.0);
    h.put("num4", "<>");
    h.put("num5", "~!@#$%^&*()_+=-`,.<>?/:;[]{}|");

    String jsonStr = g.toJson(h);
    System.out.println("JsonString::"+jsonStr);
    /*Output below ::
     * 
        JsonString::{
            "num4": "\u003c\u003e",
            "num5": "~!@#$%^\u0026*()_+\u003d-`,.\u003c\u003e?/:;[]{}|",
            "num2": 20,
            "num3": 20.0,
            "num1": 10
        }
     */

    h = g.fromJson(jsonStr, HashMap.class);

    System.out.println("convert from json String :>"+h);
    /*Output below:
      convert from json String :>{num4=<>, num5=~!@#$%^&*()_+=-`,.<>?/:;[]{}|, num2=20.0, num3=20.0, num1=10.0}
     */

    int num1= (Integer) h.get("num1");
    System.out.println(num1);
}

Exception in thread "main" java.lang.ClassCastException: java.lang.Double cannot be cast to java.lang.Integer
    at com.ps.multiupload.servlet.FileUploadUtil.main(FileUploadUtil.java:52)

回答1:


Gson works best if you tell it the type you want. Otherwise it'll always just use its favorite types: Map, List, String, Double, and Boolean.

To serialize your mixed types hash map, create a Java class that knows which types it wants:

class NumNumNum {
  int num1;
  int num2;
  double num3;
  String num4;
  String num5;
}

Deserializing JSON into a class like that will give Gson the hints it needs. With just a Map<Object, Object> it just does the simplest thing.




回答2:


Try this:

int num1=new Integer(h.get("num1").toString());

float num3=new Float(h.get("num3").toString());



回答3:


Unfortunately this is not so simple. You need to create your own deserializer. I would recommend you to copy-paste the following classes from the source codes: ObjectTypeAdapter, MapTypeAdapterFactory and aux class TypeAdapterRuntimeTypeWrapper. Now fix MapTypeAdapterFactory.create method by replacing the following line:

TypeAdapter<?> valueAdapter = gson.getAdapter(TypeToken.get(keyAndValueTypes[1]));

with

TypeAdapter<?> valueAdapter = MyObjectTypeAdapter.FACTORY.create(gson, TypeToken.get(keyAndValueTypes[1]));

Now fix ObjectTypeAdapter.read method by replacing the following line:

case NUMBER:
    return in.nextDouble();

with

case NUMBER:
    return in.nextLong();

and the last thing: register your custom map serializer in gson:

Gson gson = new GsonBuilder()
        .setPrettyPrinting()
        .registerTypeAdapterFactory(new MyMapTypeAdapterFactory(new ConstructorConstructor(Collections.<Type, InstanceCreator<?>>emptyMap()), false))
        .create();

Now any "NUMBER" data in JSON will be deserialized into long.



来源:https://stackoverflow.com/questions/10256397/json-string-contain-integer-value-while-deserialize-to-hashmap-integer-conver

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!