简介
前段时间在换成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;
}