Android:Gson将整数反序列化为双精度 [英] Android: Gson deserializes Integer as Double

查看:386
本文介绍了Android:Gson将整数反序列化为双精度的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图使用这个库


I am trying websockets on android using this library WebSocketRails-Android but I want to replace Jackson with Google's Gson but I am having a problem on deserialization. So on receiving a JSON string like this

[["websocket_rails.subscribe",{"id":1676395261,"channel":null,"user_id":null,"data":{"message":"Connected successfully to 82c6"},"success":true,"result":null,"token":null,"server_token":null}]]

Gson deserializes it and gives me the id = 1.676395261E9

I am deserializing like this

@Override
public void onStringAvailable(String data) {

    Gson gson = new Gson();
    Type type = new TypeToken<List>() {}.getType();

    List<Object> list;

    list = gson.fromJson(data, type);
    ...
}

Any help would be appreciated

UPDATE: Endend up creating a function converting that double id to an int. Thanks for your answers though.

解决方案

I had the same problem. Try this :

public final class Values {
static final Map<Class<?>, Object> defaultValues = new HashMap();

// load
static {
    defaultValues.put(boolean.class, Boolean.FALSE);
    defaultValues.put(byte.class, (byte) 0);
    defaultValues.put(short.class, (short) 0);
    defaultValues.put(int.class, 0);
    defaultValues.put(long.class, 0L);
    defaultValues.put(char.class, '\0');
    defaultValues.put(float.class, 0.0F);
    defaultValues.put(double.class, 0.0);
    defaultValues.put(Boolean.class, Boolean.FALSE);
    defaultValues.put(Byte.class, (byte) 0);
    defaultValues.put(Short.class, (short) 0);
    defaultValues.put(Integer.class, 0);
    defaultValues.put(Long.class, 0L);
    defaultValues.put(Character.class, '\0');
    defaultValues.put(Float.class, 0.0F);
    defaultValues.put(Double.class, 0.0);
}

public static final <T> T defaultValueFor(Class<T> clazz) {
    if (!defaultValues.containsKey(clazz)) return null;
    return (T) defaultValues.get(clazz);
}

}

public class ObjectAdapter implements JsonDeserializer<java.lang.Object>, InstanceCreator<java.lang.Object>, JsonSerializer<java.lang.Object> {
@Override
public Object createInstance(Type type) {
    Object result = null;
    Constructor c = null;
    final Class clazz;

    if (type instanceof ParameterizedType) {
        clazz = (Class) TypeToken.getParameterized(((ParameterizedType) type).getRawType(), ((ParameterizedType) type).getActualTypeArguments()).getRawType();
    } else {
        clazz = (Class) type;
    }
    for (Constructor construtor : clazz.getConstructors()) {
        if (c == null || c.getParameterTypes().length > construtor.getParameterTypes().length)
            c = construtor;
    }
    try {
        if (c != null && c.getParameterTypes().length > 0) {
            Object[] param = new Object[c.getParameterTypes().length];
            boolean b = c.isAccessible();
            c.setAccessible(true);
            for (int index = 0; index < c.getParameterTypes().length; index++) {
                if (c.getParameterTypes()[index].isPrimitive()) {
                    if (long.class.isAssignableFrom(c.getParameterTypes()[index]) || int.class.isAssignableFrom(c.getParameterTypes()[index]) ||
                            short.class.isAssignableFrom(c.getParameterTypes()[index]) || byte.class.isAssignableFrom(c.getParameterTypes()[index]) ||
                            float.class.isAssignableFrom(c.getParameterTypes()[index]) || double.class.isAssignableFrom(c.getParameterTypes()[index]))
                        param[index] = 0;
                    else if (char.class.isAssignableFrom(c.getParameterTypes()[index]))
                        param[index] = '\u0000';
                    else if (boolean.class.isAssignableFrom(c.getParameterTypes()[index]))
                        param[index] = false;
                    else
                        throw new RuntimeException(c.getTypeParameters()[index].getName());
                } else if (!Object.class.equals(c.getParameterTypes()[index])) {
                    param[index] = Values.defaultValueFor(c.getParameterTypes()[index]);
                } else
                    param[index] = null;
            }
            result = c.newInstance(param);
            c.setAccessible(b);
        } else if (c != null) {
            result = c.newInstance();
        }
    } catch (IllegalAccessException e) {
        e.printStackTrace();
        throw new RuntimeException(e);
    } catch (InstantiationException e) {
        e.printStackTrace();
        throw new RuntimeException(e);
    } catch (InvocationTargetException e) {
        e.printStackTrace();
        throw new RuntimeException(e);
    }
    return result;
}

@Override
public Object deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
    Object result;
    if (json.isJsonObject()) {
        result = this.createInstance(typeOfT);
        final JsonObject jsonO = json.getAsJsonObject();
        try {
            Class c = (Class) typeOfT;
            do {
                for (final Field field : c.getDeclaredFields()) {
                    if (!Modifier.isTransient(field.getModifiers()) && (!Modifier.isFinal(field.getModifiers()) && !Modifier.isStatic(field.getModifiers()))) {
                        String name = field.getType().getName() + "." + field.getName();
                        if (!jsonO.has(name))
                            name = field.getName();
                        Class type;
                        if (field.getGenericType() instanceof ParameterizedType) {
                            type = TypeToken.getParameterized(((ParameterizedType) field.getGenericType()).getRawType(), ((ParameterizedType) field.getGenericType()).getActualTypeArguments()).getRawType();
                        } else {
                            type = TypeToken.get(field.getType()).getRawType();
                        }
                        final boolean b = field.isAccessible();
                        field.setAccessible(true);
                        JsonElement element = jsonO.get(name);
                        if (String.class.isAssignableFrom(type))
                            field.set(result, element.getAsString());
                        else if (element.isJsonArray())
                            field.set(result, context.deserialize(element.getAsJsonArray(), type));
                        else if (java.lang.Object.class.isAssignableFrom(type) && !element.isJsonPrimitive())
                            field.set(result, context.deserialize(element.getAsJsonObject(), type));
                        else if (Serializable.class.isAssignableFrom(type) && element.isJsonPrimitive())
                            field.set(result, context.deserialize(element, type));
                        else
                            field.set(result, context.deserialize(element, type));
                        field.setAccessible(b);
                    }
                }
            } while ((c = c.getSuperclass()) != null);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
            throw new RuntimeException(e);
        }
    } else if (json.isJsonPrimitive()) {
        final JsonPrimitive jsonP = json.getAsJsonPrimitive();
        if (Long.class.isAssignableFrom((Class) typeOfT))
            result = jsonP.getAsLong();
        else if (Integer.class.isAssignableFrom((Class) typeOfT))
            result = jsonP.getAsInt();
        else if (Short.class.isAssignableFrom((Class) typeOfT))
            result = jsonP.getAsShort();
        else if (Byte.class.isAssignableFrom((Class) typeOfT))
            result = jsonP.getAsByte();
        else if (Double.class.isAssignableFrom((Class) typeOfT))
            result = jsonP.getAsDouble();
        else if (Float.class.isAssignableFrom((Class) typeOfT)) {
            result = jsonP.getAsFloat();
        } else if (Character.class.isAssignableFrom((Class) typeOfT)) {
            result = jsonP.getAsCharacter();
        } else if (Boolean.class.isAssignableFrom((Class) typeOfT))
            result = jsonP.getAsBoolean();
        else if (String.class.isAssignableFrom(((Class) typeOfT)))
            result = jsonP.getAsString();
        else
            throw new JsonParseException("Primitive is not supported");
    } else
        throw new JsonParseException("json is not a json Object");
    return result;
}

@Override
public JsonElement serialize(Object src, Type typeOfSrc, JsonSerializationContext context) {
    final JsonElement result;
    if (Long.class.isAssignableFrom((Class) typeOfSrc) || Integer.class.isAssignableFrom((Class) typeOfSrc) || Short.class.isAssignableFrom((Class) typeOfSrc) ||
            Byte.class.isAssignableFrom((Class) typeOfSrc) || Double.class.isAssignableFrom((Class) typeOfSrc) || Float.class.isAssignableFrom((Class) typeOfSrc)) {
        result = new JsonPrimitive((Number) src);
    } else if (Character.class.isAssignableFrom((Class) typeOfSrc)) {
        result = new JsonPrimitive((Character) src);
    } else if (Boolean.class.isAssignableFrom((Class) typeOfSrc))
        result = new JsonPrimitive((Boolean) src);
    else if (String.class.isAssignableFrom((Class) typeOfSrc))
        result = new JsonPrimitive((String) src);
    else if (Arrays.class.isAssignableFrom((Class) typeOfSrc) || ArrayList.class.isAssignableFrom((Class) typeOfSrc)) {
        result = new JsonArray();
        if (Arrays.class.isAssignableFrom((Class) typeOfSrc)) {
            for (Object object : Arrays.asList((Object[]) src)) {
                if (Long.class.isAssignableFrom(object.getClass()) || Integer.class.isAssignableFrom(object.getClass()) || Short.class.isAssignableFrom(object.getClass()) ||
                        Byte.class.isAssignableFrom(object.getClass()) || Double.class.isAssignableFrom(object.getClass()) || Float.class.isAssignableFrom(object.getClass())) {
                    ((JsonArray) result).add((Number) object);
                } else if (Character.class.isAssignableFrom(object.getClass())) {
                    ((JsonArray) result).add((Character) object);
                } else if (Boolean.class.isAssignableFrom(object.getClass()))
                    ((JsonArray) result).add((Boolean) object);
                else if (String.class.isAssignableFrom(object.getClass()))
                    ((JsonArray) result).add((String) object);
                else {
                    TypeVariable type = ((Class<ArrayList>) typeOfSrc).getTypeParameters()[0];
                    ((JsonArray) result).add(context.serialize(object, type));
                }

            }
        } else {
            ArrayList iterable = (ArrayList) src;
            for (Object object : iterable) {
                Class c = object.getClass();
                if (Long.class.isAssignableFrom(object.getClass()) || Integer.class.isAssignableFrom(object.getClass()) || Short.class.isAssignableFrom(object.getClass()) ||
                        Byte.class.isAssignableFrom(object.getClass()) || Double.class.isAssignableFrom(object.getClass()) || Float.class.isAssignableFrom(object.getClass())) {
                    ((JsonArray) result).add((Number) object);
                } else if (Character.class.isAssignableFrom(object.getClass())) {
                    ((JsonArray) result).add((Character) object);
                } else if (Boolean.class.isAssignableFrom(object.getClass()))
                    ((JsonArray) result).add((Boolean) object);
                else if (String.class.isAssignableFrom(object.getClass()))
                    ((JsonArray) result).add((String) object);
                else
                    ((JsonArray) result).add(context.serialize(object, object.getClass()));
            }
        }
    } else {
        result = new JsonObject();
        Class c = src.getClass();
        do {
            for (Field field : c.getDeclaredFields()) {
                if (!Modifier.isTransient(field.getModifiers()) && (!Modifier.isFinal(field.getModifiers()) && !Modifier.isStatic(field.getModifiers()))) {
                    final boolean b = field.isAccessible();
                    field.setAccessible(true);
                    String name = field.getName();
                    if (((JsonObject) result).has(name))
                        name = field.getType().getName() + "." + field.getName();
                    final Class type;
                    if (field.getGenericType() instanceof ParameterizedType) {
                        type = TypeToken.getParameterized(((ParameterizedType) field.getGenericType()).getRawType(), ((ParameterizedType) field.getGenericType()).getActualTypeArguments()).getRawType();
                    } else {
                        type = TypeToken.get(field.getType()).getRawType();
                    }
                    try {
                        if (type.isPrimitive()) {
                            if (Number.class.isAssignableFrom(type))
                                ((JsonObject) result).addProperty(name, (Number) field.get(src));
                            else if (Character.class.isAssignableFrom(type))
                                ((JsonObject) result).addProperty(name, (Character) field.get(src));
                            else if (Boolean.class.isAssignableFrom(type))
                                ((JsonObject) result).addProperty(name, (Boolean) field.get(src));
                            else
                                ((JsonObject) result).addProperty(name, (field.get(src) != null) ? String.valueOf(field.get(src)) : null);
                        } else if (String.class.isAssignableFrom(type))
                            ((JsonObject) result).addProperty(name, (field.get(src) != null) ? String.valueOf(field.get(src)) : null);
                        else if (Number.class.isAssignableFrom(type))
                            ((JsonObject) result).addProperty(name, (Number) field.get(src));
                        else if (Character.class.isAssignableFrom(type))
                            ((JsonObject) result).addProperty(name, (Character) field.get(src));
                        else if (Boolean.class.isAssignableFrom(type))
                            ((JsonObject) result).addProperty(name, (Boolean) field.get(src));
                        else
                            ((JsonObject) result).add(name, context.serialize(field.get(src), type));

                    } catch (IllegalAccessException e) {
                        e.printStackTrace();
                        throw new RuntimeException(e);
                    }
                    field.setAccessible(b);
                }
            }
        } while ((c = c.getSuperclass()) != null);
    }
    return result;
}
}

And this :

List<Object> list = new GsonBuilder().registerTypeHierarchyAdapter(java.lang.Object.class, new ObjectAdapter()).create().fromJson(data, type);

这篇关于Android:Gson将整数反序列化为双精度的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆