christopher christopher - 3 months ago 90
Java Question

GSON fails parsing JSON with string space

I have the following object:

public class ParameterWrapper<T> {

private String type;

private T value;

public ParameterWrapper(String type, T value) {
this.type = type;
this.value = value;
}

public String getType() {
return type;
}

public void setType(String type) {
this.type = type;
}

public T getValue() {
return value;
}

public void setValue(T value) {
this.value = value;
}
}


I am serializing it into JSON using the Gson library. When
value
contains a string with no spaces, it works perfectly. When
value
contains a string with spaces, I see the following exception:


com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Unterminated object at line 1 column 28


For the following JSON:

{"Plaintext":{"type":"String","value":"hello there"},"Key":{"type":"Number","value":"1"},"SINGLE_FUNCTION":{"value":"1-0"}}


However with the following:

{"Plaintext":{"type":"String","value":"hellothere"},"Key":{"type":"Number","value":"1"},"SINGLE_FUNCTION":{"value":"1-0"}}


The JSON is parsed successfully. Is this a known issue? I've ran the JSON through a validator and it is perfectly fine.

Edit:

The vagueness of the question wasn't unnoticed. I was hoping this was an existing issue. The application is huge, which is why prying out a small, compilable example is difficult, but I'll do what I can!

OKAY. So firstly, the below JSON is send to my controller:

@RequestMapping("/update-state")
public
@ResponseBody
String updateState(@RequestParam(value = "algorithmId") String algorithmId,
@RequestParam(value = "state") String state) throws InvalidParameterException {

Algorithm algorithm = algorithmService.getAlgorithmById(Integer.parseInt(algorithmId));
algorithm.execute(executorService.parseAlgorithmState(state));

return gsonBuilder.toJson(algorithm.getState().getParameterMap());
}


On the call to
parseAlgorithmState(state)
, it moves down to this method:

@Override
public AlgorithmState parseAlgorithmState(String json) throws InvalidParameterException {
Gson gson = new Gson();
Map keyValueMap = (Map) gson.fromJson(json.trim(), Object.class);
...


The line
Map keyValueMap = (Map) gson.fromJson(json.trim(), Object.class);
is where the exception is initially occurring.

Answer

So after some discussion, the following workaround worked:

Gson gson = new Gson(); 
JsonReader jr = new JsonReader(new StringReader(s.trim())); 
jr.setLenient(true); 
Map keyValueMap = (Map) gson.fromJson(jr, Object.class);

setLenient(true) makes the parser a bit less restrictive.

Looking at the documentation every restrictions that setLenient(true) disable are not present in your Json string, except the first one (which may be the issue since you're getting the string from a webserver).

Comments