Android:Gson将Integer反序列化为Double

时间:2016-02-10 17:08:16

标签: android json serialization gson

我正在使用这个库WebSocketRails-Android在android上尝试websockets但是我想用Google的Gson替换Jackson,但是我在反序列化方面遇到了问题。 所以收到像这样的JSON字符串

[["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反序列化它并给我id = 1.676395261E9

我像这样反序列化

@Override
public void onStringAvailable(String data) {

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

    List<Object> list;

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

任何帮助将不胜感激

更新:继续创建一个将双重id转换为int的函数。谢谢你的答案。

5 个答案:

答案 0 :(得分:0)

我之前从未见过这种情况,因此您的服务器返回内容或Gson库本身的方式可能会出错(我不这么认为)。由于您的数量小于int类型支持的范围,因此查找正在进行的操作可能会非常耗时。所以我建议你把你的ID作为String返回,然后使用Integer.parseInt();这可以解决您的问题

答案 1 :(得分:0)

创建类似以下

的java类
public class Response {
        @SerializedName("id")
        int id;
        @SerializedName("data")
        Data data;
        @SerializedName("channel")
        String channel;
        @SerializedName("user_id")
        int userId;
        @SerializedName("success")
        boolean isSuccess;
        @SerializedName("result")
        String result;
        @SerializedName("token")
        String token;
        @SerializedName("server_token")
        String serverToken;

        public int getId() {
            return id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public String getChannel() {
            return channel;
        }

        public void setChannel(String channel) {
            this.channel = channel;
        }

        public int getUserId() {
            return userId;
        }

        public void setUserId(int userId) {
            this.userId = userId;
        }

        public boolean isSuccess() {
            return isSuccess;
        }

        public void setIsSuccess(boolean isSuccess) {
            this.isSuccess = isSuccess;
        }

        public String getResult() {
            return result;
        }

        public void setResult(String result) {
            this.result = result;
        }

        public String getToken() {
            return token;
        }

        public void setToken(String token) {
            this.token = token;
        }

        public String getServerToken() {
            return serverToken;
        }

        public void getData(){
            return data;
        }

        public void setServerToken(String serverToken) {
            this.serverToken = serverToken;
        }


        public static class Data {
            @SerializedName("message")
            String message;

            public String getMessage() {
                return message;
            }

            public void setMessage(String message) {
                this.message = message;
            }
        }

    }

并以下列方式使用Gson来反序列化对象

Type type = new TypeToken<List<Response>() {}.getType();
List<Response> list = new Gson().fromJson(data, type);

// you can now get the correct int value as follows
list.get(0).getId(); // will be 1676395261

答案 2 :(得分:0)

  

Gson反序列化它并给我id = 1.676395261E9

如果正确使用Gson,则不太可能发生这种情况。如果我实现这个,我会创建一个类来将反序列化的数据检索到该类中。所以我会创建一个这样的类。

public class Response {

    private long id;
    private String channel;
    private String user_id;
    // .... Other variables
    private Data data;


    // Declare an empty constructor
    public Response() {

    }

    public class Data {
        private String message;

        public String getMessage() {
            return message;
        }
    }

    // Declare all getters
    public long getId() {
        return id;
    }

    // .... 
}

现在创建另一个类,它是一个Response列表。

public class ResponseList {

    private ArrayList<Response> list;    // Use the exact name from your json.

    // Declare an empty constructor
    public ResponseList() {

    }

    // Declare all getters
    public ArrayList<Response> getList() {
        return list;
    }
}

现在,使用Gson解析json数据

ResponseList responseList = new Gson().fromJson(data, ResponseList.class);

这里是user guide from github

答案 3 :(得分:0)

创建一个函数,将double解析为字符串,然后将适当的子字符串等转换回int。

答案 4 :(得分:0)

我遇到了同样的问题。并手动创建。

<强> DefaultValues

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

}

<强> ObjectAdapter

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 = 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 = null;
        if (json.isJsonObject()) {
            final JsonObject jsonO = json.getAsJsonObject();
            try {
                Class c = (Class) typeOfT;
                if (c.isEnum()) {
                    for (Enum<?> e : ((Enum<?>)typeOfT).getClass().getEnumConstants()) {
                        if (e.name().equals(jsonO.getAsString())) {
                            result = e;
                        }
                    }
                } else {
                    result = this.createInstance(typeOfT);
                    do {
                        for (final Field field : c.getDeclaredFields()) {
                            if (!Modifier.isTransient(field.getModifiers()) && !Modifier.isFinal(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 (element != null) {
                                    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 if (Enum.class.isAssignableFrom((Class) typeOfT))
                result = Enum.valueOf((Class<Enum>) typeOfT, 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 {
            Class c = src.getClass();
            if (c.isEnum()) {
                result = new JsonPrimitive(Enum.valueOf(c, src.toString()).toString());
            } else {
                result = new JsonObject();
                do {
                    for (Field field : c.getDeclaredFields()) {
                        if (!Modifier.isTransient(field.getModifiers()) && (!Modifier.isFinal(field.getModifiers()) && !Modifier.isStatic(field.getModifiers()))) {
                            final boolean b = field.isAccessible();
                            try {
                                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();
                                }
                                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);
                            } finally {
                                field.setAccessible(b);
                            }
                        }
                    }
                } while ((c = c.getSuperclass()) != null);
            }
        }
        return result;
    }
}

如何使用:

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