如果反序列化出错,是否有一种简单的方法可以让 Gson 跳过某个字段?
Is there an easy way to make Gson skip a field if there's an error deserializing it?
我正在尝试使用 Gson (Java) 反序列化一些数据,而我从中提取数据的 API 有时字段中的数据类型错误。 IE。如果我期望 String
类型的数组,它可能会遇到 Boolean
.
现在我意识到这些是我当前的选择:
- 总是忽略反序列化的字段
- 创建自定义
TypeAdapter
来执行反序列化并捕获错误并执行某些操作(例如将字段设置为 null
)
但是我想问的是是否有另一种方法可以轻松做到这一点,所以如果在解析某个字段时出现异常,Gson 将忽略该字段。像 @Skippable
这样的字段上的注释或者使用 GsonBuilder
创建 Gson
对象时的设置?
有人熟悉这种东西吗?
要妥善处理 JSON
中所有可能的错误以及 payload 与 POJO
模型之间的不匹配并不是一件容易的事。但是我们可以尝试实现 com.google.gson.TypeAdapterFactory
接口并将所有默认 TypeAdapter
包装在 try-catch
中并跳过无效数据。示例解决方案可能如下所示:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class GsonApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
Gson gson = new GsonBuilder()
.setLenient()
.registerTypeAdapterFactory(new IgnoreFailureTypeAdapterFactory())
.create();
Entity entries = gson.fromJson(new FileReader(jsonFile), Entity.class);
System.out.println(entries);
}
}
class IgnoreFailureTypeAdapterFactory implements TypeAdapterFactory {
public final <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type);
return createCustomTypeAdapter(delegate);
}
private <T> TypeAdapter<T> createCustomTypeAdapter(TypeAdapter<T> delegate) {
return new TypeAdapter<T>() {
@Override
public void write(JsonWriter out, T value) throws IOException {
delegate.write(out, value);
}
@Override
public T read(JsonReader in) throws IOException {
try {
return delegate.read(in);
} catch (Exception e) {
in.skipValue();
return null;
}
}
};
}
}
class Entity {
private Integer id;
private String name;
// getters, setters, toString
}
例如,上面的代码打印:
Entity{id=null, name='1'}
以下 JSON
负载:
{
"id": [
{
"a": "A"
}
],
"name": 1
}
另请参阅:
- Same object referenced in two classes, duplicated instance after decode
我正在尝试使用 Gson (Java) 反序列化一些数据,而我从中提取数据的 API 有时字段中的数据类型错误。 IE。如果我期望 String
类型的数组,它可能会遇到 Boolean
.
现在我意识到这些是我当前的选择:
- 总是忽略反序列化的字段
- 创建自定义
TypeAdapter
来执行反序列化并捕获错误并执行某些操作(例如将字段设置为null
)
但是我想问的是是否有另一种方法可以轻松做到这一点,所以如果在解析某个字段时出现异常,Gson 将忽略该字段。像 @Skippable
这样的字段上的注释或者使用 GsonBuilder
创建 Gson
对象时的设置?
有人熟悉这种东西吗?
要妥善处理 JSON
中所有可能的错误以及 payload 与 POJO
模型之间的不匹配并不是一件容易的事。但是我们可以尝试实现 com.google.gson.TypeAdapterFactory
接口并将所有默认 TypeAdapter
包装在 try-catch
中并跳过无效数据。示例解决方案可能如下所示:
import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import com.google.gson.TypeAdapter;
import com.google.gson.TypeAdapterFactory;
import com.google.gson.reflect.TypeToken;
import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
public class GsonApp {
public static void main(String[] args) throws Exception {
File jsonFile = new File("./resource/test.json").getAbsoluteFile();
Gson gson = new GsonBuilder()
.setLenient()
.registerTypeAdapterFactory(new IgnoreFailureTypeAdapterFactory())
.create();
Entity entries = gson.fromJson(new FileReader(jsonFile), Entity.class);
System.out.println(entries);
}
}
class IgnoreFailureTypeAdapterFactory implements TypeAdapterFactory {
public final <T> TypeAdapter<T> create(Gson gson, TypeToken<T> type) {
final TypeAdapter<T> delegate = gson.getDelegateAdapter(this, type);
return createCustomTypeAdapter(delegate);
}
private <T> TypeAdapter<T> createCustomTypeAdapter(TypeAdapter<T> delegate) {
return new TypeAdapter<T>() {
@Override
public void write(JsonWriter out, T value) throws IOException {
delegate.write(out, value);
}
@Override
public T read(JsonReader in) throws IOException {
try {
return delegate.read(in);
} catch (Exception e) {
in.skipValue();
return null;
}
}
};
}
}
class Entity {
private Integer id;
private String name;
// getters, setters, toString
}
例如,上面的代码打印:
Entity{id=null, name='1'}
以下 JSON
负载:
{
"id": [
{
"a": "A"
}
],
"name": 1
}
另请参阅:
- Same object referenced in two classes, duplicated instance after decode