我在尝试将json数组带到对象列表时遇到错误,例外情况如下。
com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 170
这是我正在尝试使用的代码
public static void main(String[] args) throws FileNotFoundException {
Gson gson = new Gson();
Test test = new Test();
JsonElement json = gson.fromJson(test.getFile("fieldTypes.json"), JsonElement.class);
String result = gson.toJson(json);
System.out.println(result);
Type listType = new TypeToken<ArrayList<JiraField>>(){}.getType();
JiraField[] jiraFields = gson.fromJson(result, listType);
for (JiraField jiraField : jiraFields) {
System.out.println(jiraField);
}
}
这是文件内容
[
{
"id": "issuetype",
"key": "issuetype",
"name": "Issue Type",
"custom": false,
"orderable": true,
"navigable": true,
"searchable": true,
"clauseNames": [
"issuetype",
"type"
],
"schema": {
"type": "issuetype",
"system": "issuetype"
}
},
{
"id": "timespent",
"key": "timespent",
"name": "Time Spent",
"custom": false,
"orderable": false,
"navigable": true,
"searchable": false,
"clauseNames": [
"timespent"
],
"schema": {
"type": "number",
"system": "timespent"
}
}
]
正在从资源文件夹中读取文件但是工作正常,并且sysout正确显示了json内容。我认为我做错了什么?
答案 0 :(得分:0)
在对象中为所需字段添加@Expose注释
public class JiraField {
@Expose
private String id ;
@Expose private String key ;
@Expose private String name ;
@Expose private boolean custom ;
@Expose private boolean orderable ;
@Expose private boolean navigable ;
@Expose private String[] clauseNames ;
然后当你初始化gson时,就像这样做
Gson gson = new GsonBuilder().excludeFieldsWithoutExposeAnnotation().create();
然后它起作用:)
JiraFields{id='issuetype', key='issuetype', name='Issue Type', custom=false, orderable=true, navigable=true, clauseNames=[issuetype, type]}
JiraFields{id='timespent', key='timespent', name='Time Spent', custom=false, orderable=false, navigable=true, clauseNames=[timespent]}
答案 1 :(得分:0)
试试这个:
Type listType = new TypeToken<ArrayList<JiraField[]>>(){}.getType();
我认为我们需要按顺序指定JiraField []以获取Array。
答案 2 :(得分:0)
我假设您根据异常消息...at line 1 column 170...
拥有缩小的JSON。如果您提供完全正确的JSON文档和映射也会很好,因为发布的格式化JSON现在已经破坏了布局。我还假设您的映射是自定义的,基本上类似于:
final class JiraField {
@SerializedName("id")
final String id = null;
@SerializedName("key")
final String key = null;
@SerializedName("name")
final String name = null;
@SerializedName("custom")
final boolean isCustom = Boolean.valueOf(false);
@SerializedName("orderable")
final boolean isOrderable = Boolean.valueOf(false);
@SerializedName("navigable")
final boolean isNavigable = Boolean.valueOf(false);
@SerializedName("searchable")
final boolean isSearchable = Boolean.valueOf(false);
@SerializedName("clauseNames")
final List<String> clauseNames = null;
@SerializedName("schema")
final List<String> schema = null;
}
请注意JiraField.schema
字段类型:它是一个列表。尝试使用默认的Gson配置反序列化JiraField
列表将导致:
java.lang.IllegalStateException:预期为BEGIN_ARRAY,但在第1行第170行路径为$ [0] .schema
时为BEGIN_OBJECT
症状和列完全相同(但是,我只是简化你的JSON文件的缩小),但请注意你可能错过的路径$[0].schema
:它说的是数组开始标记[
是预期的(因为该字段是List<String>
),但它是一个对象开始标记{
。将字段类型更改为更合适的任意Map<String, String>
或任何其他自定义的适当POJO将修复它。部分。
@SerializedName("schema")
final Map<String, String> schema = null;
为何部分?您的类型令牌已绑定到ArrayList
,但您将反序列化结果转换为数组JiraField[]
,因此您可以获得以下内容:
线程中的异常&#34; main&#34; java.lang.ClassCastException:java.util.ArrayList无法强制转换为[LJiraField;
要修复它,你必须声明与反序列化值类型匹配的jiraFields
变量:它是一个数组列表,但不是数组 - 这些在Java中是不一样的。
List<JiraField> jiraFields = ...
关于反序列化的另一个注意事项是,您不需要中间json
对象来反序列化。 test.getFile
最有可能返回java.io.Reader
,因此您可以直接将其传递给反序列化。总结一下,以下内容适合您:
// Immutable and thread-safe, can be instantiated once and shared
private static final Gson gson = new Gson();
// Immutable and thread-safe value type, the same story, + List instead of ArrayList - interfaces are usually much better
private static final Type listType = new TypeToken<List<JiraField>>() {
}.getType();
public static void main(final String... args)
throws IOException {
try ( final Reader reader = test.getFile("fieldTypes.json") ) {
final List<JiraField> jiraFields = gson.fromJson(reader, listType);
for ( final JiraField jiraField : jiraFields ) {
System.out.println(jiraField.key + " => " + jiraField.name);
}
}
}
输出:
issuetype =&gt;问题类型
timespent =&gt;花费的时间
答案 3 :(得分:0)
Type listType = new TypeToken<ArrayList<JiraField>>(){}.getType();
ArrayList<JiraField> jiraFields = gson.fromJson(result, listType);
for (JiraField jiraField : jiraFields) {
System.out.println(jiraField);
}
尝试此代码
答案 4 :(得分:0)
评论此行
Type listType = new TypeToken<ArrayList<JiraField>>(){}.getType();
试试这个
JiraField[] jiraFields = gson.fromJson(result, JiraField[].class);