Gson解析了不带引号的值

时间:2013-12-13 00:39:18

标签: java gson

我在我的项目GSON库中使用,一切都很好,但现在我遇到了一个问题,我需要在不带引号的值上使用自定义反序列化器。

我有以下值,需要从json解析:

  

[[“county”,“=”,field_name],[“name”,“ilike”,“username”]]

我需要使用自定义反序列化器将不带引号的值解析为包装类,如:

public class StringField {
    private String value;

    public String getValue() {
        return value;
    }

}

值将“field_name”作为字符串。

3 个答案:

答案 0 :(得分:2)

问题是数据有效JSON

JSON 允许这样的“非引用值”字符串,例如field_name,Gson也不允许。修复输入以使其 有效JSON(可能是"$field_name$") - 或者使用可以处理类似JSON的非JSON文本的工具(即非Gson)。

这种情况无法Custom Deserialization更正,因为数据甚至没有正确解析为Json令牌:Gson会在遇到无效/非JSON时抛出异常

至少,这需要创建一个自定义 JsonReader实现,可以将“barewords”作为字符串读取。但是,这是有问题的,因为JsonReader不符合任何专用接口(因此它必须是子类,oops!)并且是最终的(因此它不能被子类化,oops!)。因此,除非愿意编辑Gson库源:不可能。

答案 1 :(得分:2)

使用下面的代码,我解决了你的JSON没有问题,我离开Gson决定如何解析它,除了假设它包含一个List最外层。结果是List List的{​​{1}}个String。我不太清楚为什么你需要StringField课程。

package stackoverflow.questions;

import java.util.List;

import com.google.gson.*;

public class Q20557131 {

   public static void main(String[] args){

      String json = "[[\"county\",\"=\", field_name], [\"name\", \"ilike\", \"username\"]]";
      Gson g = new Gson();
      List outerList = g.fromJson(json, List.class);


      List innerList = (List) outerList.get(0);
      for(Object o: innerList)
         System.out.println(o.getClass());

   }
}

默认情况下,即使lenient属性设置为false,Gson 2.2.4也是宽松的,来自documentation

  

配置此解析器在接受的内容中是自由的。默认情况下,此解析器是严格的,只接受RFC 4627指定的JSON。将解析器设置为lenient会导致它忽略以下语法错误:

     

...

     

不带引号或“单引号”的字符串。

     

...

即使文档默认情况下该属性为false,也在JsonReader#fromJson的源代码中:

 public <T> T fromJson(JsonReader reader, Type typeOfT) throws JsonIOException, JsonSyntaxException {
    boolean isEmpty = true;
    boolean oldLenient = reader.isLenient();
    reader.setLenient(true); <-- always true
    try {
      reader.peek();
      isEmpty = false;
      TypeToken<T> typeToken = (TypeToken<T>) TypeToken.get(typeOfT);
      TypeAdapter<T> typeAdapter = getAdapter(typeToken);
      T object = typeAdapter.read(reader);
      return object;
    } catch (EOFException e) {
    ...

答案 2 :(得分:0)

我多年前以另一种方式解决了这个问题(抱歉延迟了)。编写了符号预处理器类,它用rendxp标签(如 field_name )替换为model中的实际值,然后解析为json。