问题
I have the following class :
final class CFS {
public Map<String, String> files = new HashMap<String, String>();
public List<String> directories = new ArrayList<String>();
}
And this code which should parse the json :
CFS cfs = JStorage.getGson().fromJson(JSON_STRING, CFS.class);
Where
JSON_STRING = "{\"directories\" : [\"folder1\", \"folder1/folder2\"], \"files\" : [{\"folder1\" : \"file.txt\"}, {\"folder1/folder2\" : \"file.cfg\"}]}"
JSON is:
{
"directories": ["folder1", "folder1/folder2"],
"files": [
{
"folder1": "file.txt"
},
{
"folder1/folder2": "file.cfg"
}
]
}
The error I'm getting is: Expected BEGIN_ARRAY but was STRING at line 1 column 62
But I have no idea why, the json is valid according to jsonlint.
Any idea on why I am getting this error?
回答1:
Your JSON is valid - but your mapping class isn't (parts of it don't match). In particular, the files property of your class cannot be mapped as a Map<String, String> from the given JSON. It's hard to recommend an alternate structure for storing the data without seeing a larger sample, but in general you can follow this guide when mapping between JSON structures and Java classes. This JSON:
"files": [
{
"folder1": "file.txt"
},
{
"folder1/folder2": "file.cfg"
}
]
represents an array containing objects, where each object is best represented as a map. So in essence, a list of maps. Consequently your Java object should be:
public class CFS {
private List<Map<String, String>> files = new ArrayList<Map<String, String>>(
4);
private List<String> directories = new ArrayList<String>(4);
// Constructors, setters/getters
}
Note that I've corrected your properties by making them private and adding getters/setters. With the above defined class your program should work just fine.
final Gson gson = new GsonBuilder().create();
final CFS results = gson.fromJson(json, CFS.class);
Assert.assertNotNull(results);
Assert.assertNotNull(results.getFiles());
System.out.println(results.getFiles());
Produces:
[{folder1=file.txt}, {folder1/folder2=file.cfg}]
If you find yourself needing to retain the current CFS structure though, you would need to manually parse the JSON into it.
回答2:
If someone is getting this error in AndroidStudio :
Try two things:
- Roll back to last working conditions. (Revert if you use VCS).
- In build options Clean project and rebuild. (Worked for me.)
I'm fairly new to android. Excuse any mistakes if committed. Suggestions are welcome :)
回答3:
As already Brain noted you have a array of objects so you need to convert this by your own with a custom deserializer.
Here is an example implementation:
public class q16380367 {
final class CFS {
public HashMap<String, String> files = new HashMap<String, String>();
public ArrayList<String> directories = new ArrayList<String>();
}
public static void main(String[] args) {
new q16380367();
}
public q16380367() {
String JSON_STRING = "{\"directories\" : [\"folder1\", \"folder1/folder2\"], \"files\" : [{\"folder1\" : \"file.txt\"}, {\"folder1/folder2\" : \"file.cfg\"}]}";
Gson gson = new GsonBuilder().registerTypeAdapter(
new TypeToken<HashMap<String, String>>() {
}.getType(), new CfsDeserializer()).create();
CFS foo = gson.fromJson(JSON_STRING, CFS.class);
}
private final class CfsDeserializer implements
JsonDeserializer<HashMap<String, String>> {
@Override
public HashMap<String, String> deserialize(JsonElement json,
Type typeOfT, JsonDeserializationContext context)
throws JsonParseException {
HashMap<String, String> data = new HashMap<String, String>();
JsonArray list = json.getAsJsonArray();
for (JsonElement e : list) {
Set<Entry<String, JsonElement>> entries = e.getAsJsonObject()
.entrySet();
for (Entry<String, JsonElement> entry : entries) {
data.put(entry.getKey(), entry.getValue().getAsString());
}
}
return data;
}
}
}
来源:https://stackoverflow.com/questions/16380367/gson-expected-begin-array-but-was-string-at-line-1-column-62