简介
前段时间在换成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;
@Exclude
String gender;
}
参考
[1]:http://stackoverflow.com/questions/4802887/gson-how-to-exclude-specific-fields-from-serialization-without-annotations .
[2]:http://stackoverflow.com/questions/10596667/how-to-invoke-default-deserialize-with-gson .