我试图使用gson处理json文件,但我遇到了一个奇怪的错误。我从中读取的json(并且不能修改)有一种处理空字段的奇怪方法。它将[]置于没有数据的地方,导致gson认为它是一个数组,当它期待一个对象时。
gson的一个例子:
//non-empty field
"prizes":[
{
"year":"1902",
"category":"physics",
"share":"2",
"motivation":"\"in recognition of the extraordinary service they rendered by their researches into the influence of magnetism upon radiation phenomena\"",
"affiliations":[
{
"name":"Leiden University",
"city":"Leiden",
"country":"the Netherlands"
}
]
}
]
//empty field
"prizes":[
{
"year":"1903",
"category":"physics",
"share":"4",
"motivation":"\"in recognition of the extraordinary services they have rendered by their joint researches on the radiation phenomena discovered by Professor Henri Becquerel\"",
"affiliations":[
[]
]
}
]
这是我处理json的代码:
public static void main(String[] args) throws IOException {
// Get Gson object
Gson gson = new Gson();
// read JSON file data as String
String fileData = new
String(Files.readAllBytes(Paths.get("laureates.json")));
// parse json string to object
Example laur = gson.fromJson(fileData, Example.class);
// print object data
System.out.println("\n\nLaureates Object\n\n" + laur);
}
我已经设置了所有课程,我相信一旦这个问题得到解决,它就会起作用。 我得到的错误是"预期BEGIN_OBJECT但是在第1行第3401行"是BEGIN_ARRAY。 (第3401列是第一个[])
的确切位置答案 0 :(得分:0)
设置空对象的正确方法是没有括号。你知道的。 : - )
"prizes":[
{
"year":"1903",
"category":"physics",
"share":"4",
"motivation":"\"in recognition of the extraordinary services they have rendered by their joint researches on the radiation phenomena discovered by Professor Henri Becquerel\"",
"affiliations":[
]
}
]
您可以删除括号。
fileData = fileData.replaceAll("\\[]", "");
我希望这会有所帮助。
答案 1 :(得分:0)
看起来gson期待一个对象但是返回了数组 尝试将Example更改为数组,如下所示。
Example[] emps= gson.fromJson(yourJson, Example
[].class);
另请参阅相关的GSON throwing "Expected BEGIN_OBJECT but was BEGIN_ARRAY"?
答案 2 :(得分:0)
您始终可以使用类型适配器来调整设计错误但格式正确的JSON文档。例如,以下类型适配器可以修复您的情况:
final class EmptyListFixTypeAdapterFactory
implements TypeAdapterFactory {
private static final TypeAdapterFactory instance = new EmptyListFixTypeAdapterFactory();
private EmptyListFixTypeAdapterFactory() {
}
static TypeAdapterFactory get() {
return instance;
}
@Override
public <T> TypeAdapter<T> create(final Gson gson, final TypeToken<T> typeToken) {
// If it's not a list, then just let Gson pass through the rest of the type adapters chain
if ( !List.class.isAssignableFrom(typeToken.getRawType()) ) {
return null;
}
// Get the original List adapter - we'll use it below
@SuppressWarnings("unchecked")
final TypeAdapter<List<Object>> delegateTypeAdapter = (TypeAdapter<List<Object>>) gson.getDelegateAdapter(this, typeToken);
// Wrap it
@SuppressWarnings("unchecked")
final TypeAdapter<T> typeAdapter = (TypeAdapter<T>) EmptyListFixTypeAdapter.get(delegateTypeAdapter);
return typeAdapter;
}
private static final class EmptyListFixTypeAdapter<E>
extends TypeAdapter<List<E>> {
// JsonParser as of Gson 2.8.2 holds no state
private static final JsonParser jsonParser = new JsonParser();
private final TypeAdapter<List<E>> delegateTypeAdapter;
private EmptyListFixTypeAdapter(final TypeAdapter<List<E>> delegateTypeAdapter) {
this.delegateTypeAdapter = delegateTypeAdapter;
}
private static <E> TypeAdapter<List<E>> get(final TypeAdapter<List<E>> delegateTypeAdapter) {
return new EmptyListFixTypeAdapter<>(delegateTypeAdapter)
.nullSafe(); // A convenient method to add null-checking automatically
}
@Override
public void write(final JsonWriter out, final List<E> value)
throws IOException {
// In case if you need to produce document with this quirks
if ( value.isEmpty() ) {
out.beginArray();
out.beginArray();
out.endArray();
out.endArray();
return;
}
delegateTypeAdapter.write(out, value);
}
@Override
public List<E> read(final JsonReader in) {
final JsonElement jsonElement = jsonParser.parse(in);
final JsonArray array = jsonElement.getAsJsonArray();
// Is it [[]]?
if ( array.size() == 1 ) {
final JsonElement element = array.get(0);
if ( element.isJsonArray() && ((JsonArray) element).size() == 0 ) {
// Yes, detected
return new ArrayList<>();
}
}
// No, proceed with the delegate type adapter
return delegateTypeAdapter.fromJsonTree(array);
}
}
}
现在假设您有以下映射:
final class Laureate {
final List<Prize> prizes = new ArrayList<>();
}
final class Prize {
final int year = Integer.valueOf(0);
final String category = null;
final List<Affiliation> affiliations = new ArrayList<>();
}
final class Affiliation {
final String name = null;
final String city = null;
final String country = null;
}
然后:
private static final Gson gson = new GsonBuilder()
.registerTypeAdapterFactory(EmptyListFixTypeAdapterFactory.get())
.create();
private static final Type laureatesType = new TypeToken<List<Laureate>>() {
}.getType();
public static void main(final String... args)
throws IOException {
try ( final JsonReader jsonReader = Resources.getPackageResourceJsonReader(Q49603826.class, "laureates.json") ) {
gson.<List<Laureate>>fromJson(jsonReader, laureatesType)
.stream()
.flatMap(laureate -> laureate.prizes.stream())
.peek(prize -> System.out.println("Prize: " + prize.year + " " + prize.category))
.flatMap(prize -> prize.affiliations.stream())
.peek(affiliation -> System.out.println("\tAffiliation: " + affiliation.name + " " + affiliation.city + " " + affiliation.country))
.forEach(affiliation -> {
});
}
}
输出:
奖项:1902年物理学 ........隶属:莱顿大学莱顿荷兰
奖项:1903年物理学