我将一些Json序列化为Java对象时遇到了一些困难。如您所见,Json位包含顶级元素args
,其中包含一个对象列表,其中包含String
作为键和混合值的值。我在Java源文件中尝试了一些创造性的东西:
的Json
{
"args": {
"all": {
"expectCliArgs": true
},
"Prog3a": {
"expectedNumberOfCliArgs": 2,
"expectedErrorMessage": "Usage: java Prog3a infilename searchword"
},
"Prog3b": {
"expectedNumberOfCliArgs": 2,
"expectedErrorMessage": "Usage: java Prog3b infileName outfileName"
},
"Prog3c": {
"expectedNumberOfCliArgs": 1,
"expectedErrorMessage": "Usage: java Prog3c infileName"
}
}
}
爪哇
protected class Args {
public Map<String, Set<Map<String, Object>>> map = new HashMap<>(); // no dice
}
protected class Args {
public Map<String, Set<Map<String, ?>>> map = new HashMap<>(); // no dice
}
我可能需要custom serializer吗?
更新 我试着在课堂上做以下几点(按照答案):
private Map<String, Set<ExpectedArgs>> args = new HashMap<>();
protected class ExpectedArgs {
public Boolean expectCliArgs;
public Integer expectedNumberOfCliArgs;
public String expectedArgsErrorMessage;
}
但现在好像Gson抱怨我的Json文件的语法:
Exception in thread "main" com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 847
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:176)
at com.google.gson.Gson.fromJson(Gson.java:803)
at com.google.gson.Gson.fromJson(Gson.java:768)
at com.google.gson.Gson.fromJson(Gson.java:717)
at com.google.gson.Gson.fromJson(Gson.java:689)
at javaGrader.config.ParseConfig.convertJsonToObject(ParseConfig.java:72)
at javaGrader.config.ParseConfig.parseConfig(ParseConfig.java:34)
at javaGrader.JavaGrader.main(JavaGrader.java:60)
Disconnected from the target VM, address: '127.0.0.1:62344', transport: 'socket'
Caused by: java.lang.IllegalStateException: Expected BEGIN_ARRAY but was BEGIN_OBJECT at line 1 column 847
at com.google.gson.stream.JsonReader.beginArray(JsonReader.java:338)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:79)
at com.google.gson.internal.bind.CollectionTypeAdapterFactory$Adapter.read(CollectionTypeAdapterFactory.java:60)
at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.read(TypeAdapterRuntimeTypeWrapper.java:40)
at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:187)
at com.google.gson.internal.bind.MapTypeAdapterFactory$Adapter.read(MapTypeAdapterFactory.java:145)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.read(ReflectiveTypeAdapterFactory.java:93)
at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read(ReflectiveTypeAdapterFactory.java:172)
... 7 more
我在我的Json文件中设置了一些断点,看起来“args”对象是导致胃灼热的对象。作为参考,这里是full Json file,java Config class和the class where Gson runs。看起来Gson将我的对象与数组混淆。
Col 847是:
searchword"},"Prog3b":{
^
有什么想法吗?
更新2 我对变量的签名不正确:
private Map<String, Set<ExpectedArgs>> args = new HashMap<>(); // wrong
private Map<String, ExpectedArgs> args = new HashMap<>(); // right
答案 0 :(得分:2)
我会为包含两组字段的内部对象定义一个类,如下所示:
public static class ExpectedArgs {
public Boolean expectCliArgs;
public Integer expectedNumberOfCliArgs;
public String expectedErrorMessage;
}
(注意我在这里故意使用Boolean
和Integer
而不是boolean
和int
,这样您就可以通过测试{{{{}}来判断该字段是否已设置1}}。)
然后你可以像这样定义外部类:
null
最后,您可以将JSON反序列化为public static class Data {
public Map<String, ExpectedArgs> args;
}
:
Data
此代码为您的示例JSON输出以下内容:
String json = "...";
Gson gson = new Gson();
Data data = gson.fromJson(json, Data.class);
data.args.forEach((key, value) -> {
System.out.println(key);
System.out.println(value.expectCliArgs);
System.out.println(value.expectedNumberOfCliArgs);
System.out.println(value.expectedErrorMessage);
System.out.println();
});