Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

GSON fails parsing JSON with string space

Tags:

java

json

gson

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.

like image 996
christopher Avatar asked Oct 19 '25 15:10

christopher


2 Answers

I just had this same issue. The problem is that the character is a non-breaking space, char(160). If you paste this in the body of a request using POSTMAN, you'll visually be able to see the characters (They look like gray dots). Gson doesn't like them.

like image 199
Richard Anderson Avatar answered Oct 21 '25 06:10

Richard Anderson


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).

like image 24
Alexis C. Avatar answered Oct 21 '25 06:10

Alexis C.



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!