简介
前段时间在换成gson 重写下解析遇到一些问题,之前是使用JSONObject 进行解析,在使用GSON 之后发现解析数据错误和获取不到值得问题。
后台格式不规范
例如: 有值时返回: { person:{"name":"wang",age=17} } 有没有值时返回: { person:[] } 这个时候用gson就会抛出解析异常。 **解决方案:**(使用 TypeAdapterFactory)
final static class SafeTypeAdapterFactory implements TypeAdapterFactory{ @Override public TypeAdapter create(Gson gson, final TypeToken type) { final TypeAdapter delegate = gson.getDelegateAdapter(this,type); return new TypeAdapter() { @Override public void write(JsonWriter out, T value) throws IOException { try { delegate.write(out, value); } catch (IOException e) { delegate.write(out, null); } } @Override public T read(JsonReader in) throws IOException { try { return delegate.read(in); } catch (IOException e) { in.skipValue(); return null; } catch (IllegalStateException e) { in.skipValue(); return null; } catch (JsonSyntaxException e) { in.skipValue(); if(type.getType() instanceof Class){ try { return (T) ((Class)type.getType()).newInstance(); } catch (Exception e1) { } } return null; } } }; } }
使用GSON 时:
Gson myGson = new GsonBuilder().registerTypeAdapterFactory(new SafeTypeAdapterFactory()).create();
例如解析下面这样的bean:
class Bean{ Inner in; String a; String b; class Inner{ String c; } }
返回的Bean 就会是 in = new Inner();
其他的异常就会赋值为null,具体可以根据自己需要修改。
2. 解析bool 类型时服务器有两个写法:第一种 True 或者 False ,第二种 0 代表 False 1 代表 True。
我在bean 中都使用 boolean 来表示该值
解决方案:(使用TypeAdapter)
Gson myGson = new GsonBuilder() .registerTypeAdapter(boolean.class, new JsonDeserializer<Boolean>() { @Override public Boolean deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException { try { return json.getAsInt() == 1; }catch (NumberFormatException e){ return json.getAsBoolean(); } } }).create();
3.对于bean 中有部分属性需要忽略
解决方案:(使用ExclusionStrategy)
创建注解类 Exclude
@Retention(RetentionPolicy.RUNTIME)@Target(ElementType.FIELD)public @interface Exclude { }
在gson中配置 忽略带有Exclude的属性:
Gson gson = new GsonBuilder() .setExclusionStrategies(new ExclusionStrategy(){ @Override public boolean shouldSkipField(FieldAttributes f) { return f.getAnnotation(Exclude.class) != null; } @Override public boolean shouldSkipClass(Class<?> clazz) { return false; } })
使用时在需要忽略的属性上标记@Exclude 即可:
class Mock{ String name; String age;@ExcludeString gender; }