特殊字符打破杰森

时间:2018-08-15 07:16:07

标签: java json gson

我需要使用包含大量特殊字符和空格的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或任何其他包含特殊字符的字符串,则它将中断。

那么有没有办法解决这个问题?或者,有没有比使用此库更好的解决方案?

预先感谢

2 个答案:

答案 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);
    }