3

I using in my project GSON library, everything is fine, but now i'm stuck with a problem, where i need to use a custom deserializer on unquoted values.

I have the following value, and need to parse from json:

[ ["county","=", field_name], ["name", "ilike", "username"] ]

I need to parse unquoted values with a custom deserializer, to a wrapper class like:

public class StringField {
    private String value;

    public String getValue() {
        return value;
    }

}

And value will have "field_name" as string.

Carlos Robles
  • 10,828
  • 3
  • 41
  • 60
h32
  • 41
  • 5

3 Answers3

2

The problem is that the data is not valid JSON.

JSON does not permit such "unquoted value" strings such as field_name and neither does Gson. Either fix the input such that it is valid JSON (perhaps "$field_name$") - or use a tool (i.e. not Gson) that can cope with non-JSON text that resembles JSON.

This situation can't be corrected with Custom Deserialization because the data isn't even parsed correctly to Json tokens: Gson will throw an exception as the invalid/non-JSON is encountered.

At the very least this would require creating a customized JsonReader implementation that can read "barewords" as strings. However, this is problematic to do because JsonReader does not conform to any specialized interfaces (so it must be subclassed, oops!) and is final (so it can't be subclassed, oops!). As such, unless willing to edit the Gson library source: not possible.

user2864740
  • 60,010
  • 15
  • 145
  • 220
2

With the below code, I parsed your JSON without problems, I left Gson decide how to parse it, except assuming it contained a List outermost. And the result was a List of Lists of Strings. I did not understand very well why you need StringField class.

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());

   }
}

By default, Gson 2.2.4 is lenient, even if has the lenient property set to false, from documentation

Configure this parser to be be liberal in what it accepts. By default, this parser is strict and only accepts JSON as specified by RFC 4627. Setting the parser to lenient causes it to ignore the following syntax errors:

....

Strings that are unquoted or 'single quoted'.

...

even if documentation states that property is false by default, in the source code of the 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) {
    ...
giampaolo
  • 6,906
  • 5
  • 45
  • 73
0

I've solved this problem years ago in another way (sorry for delayed). Wrote symbolic preprocessor class, which replace by regexp labels like field_name with actual values from model and then parsed json.

h32
  • 41
  • 5