我需要使用包含大量特殊字符和空格的Jsons。我在堆栈上的其他地方看到Gson库(用于Java)做得很好,所以我正在使用它。在使用fromJson(Json字符串,对象类)方法将Json字符串转换为对象时,我注意到,一旦字符串中的数据包含任何特殊字符或空格,就会引发异常(Unterminated object)。删除特殊字符可以使其按预期工作。
为了更好地说明这种情况:
ArrayList<Person> people = new ArrayList<Person>();
Person p1 = new Person("Matteo", 999);
Person p2 = new Person("Adam", 999);
Person p3 = new Person("Steve", 999);
people.add(p1);
people.add(p2);
people.add(p3);
String json = new Gson().toJson(people);
System.out.println(json);
ArrayList people2 = new Gson().fromJson(json, ArrayList.class);
for (int i = 0; i < people2.size(); i++) {
Person pn = new Gson().fromJson(people2.get(i).toString(), Person.class);
System.out.println(people2.get(i).toString());
System.out.println(pn.name);
}
class Person {
String name;
int age;
Person(String cname, int cage) {
name = cname;
age = cage;
}
}
上面的代码按预期工作,但是,如果我不是Matteo而是输入Ma:tteo或Ma tteo或任何其他包含特殊字符的字符串,则它将中断。
那么有没有办法解决这个问题?或者,有没有比使用此库更好的解决方案?
预先感谢
答案 0 :(得分:2)
Gson
可以正常工作。
使用Gson库的方式有两个问题:
您将fromJson(String, Class<T>)
与泛型结合使用。该文档指出,使用泛型时,应使用fromJson(String, Type)
:
对于对象是通用类型的情况,请调用
fromJson(String, Type)
。
您首先要将JSON字符串反序列化为Java结构(在您的情况下为ArrayList
),然后在其上循环,对于每个对象,您都将再次反序列化它,具体取决于toString()
中包含的对象的ArrayList
方法。实际上,您的列表根本不包含Person
个对象,而是包含LinkedTreeMap
包中的com.google.gson.internal
个对象。您可以通过调用people2.get(i).getClass()
来获取对象的类。
您真的不需要遍历此ArrayList
的元素并自己反序列化这些元素。如果需要遍历结构中包含的每个列表,那么当该结构比您的结构更复杂时,将是一个很大的伤害。
只需摆脱for循环,然后将对toJson(String, Class<T>)
的调用替换为对fromJson(String, Type)
的调用。就是这样。
// We're using the TypeToken class, to handle generic types
Type type = new TypeToken<List<Person>>() { }.getType();
List<Person> newPeople = new Gson().fromJson(json, type);
// Print all names
newPeople.stream()
.map(t -> t.name)
.forEach(System.out::println);
注释
该问题的部分原因是您正在使用 raw type (ArrayList
)。不要使用原始类型,仅允许向后兼容。
我需要处理包含特殊字符和空格的Json。
使用特殊字符仍不清楚您的意思。 JSON standard清楚地定义了允许和不允许的内容。您的JSON字符串应符合标准,然后就可以了。
答案 1 :(得分:1)
尝试使用此代码。
ArrayList<Person> people = new ArrayList<Person>();
Person p1 = new Person("Ma:tteo", 999);
Person p2 = new Person("Adam", 999);
Person p3 = new Person("Steve", 999);
people.add(p1);
people.add(p2);
people.add(p3);
Gson gson = new Gson();
String json = gson.toJson(people);
System.out.println(json);
List<Person> personList = gson.fromJson(json, new TypeToken<List<Person>>(){}.getType());
for (int i = 0; i < personList.size(); i++) {
Person person = personList.get(i);
System.out.println(person.toString());
System.out.println(person.name);
}