とあるJSONの構文不正
とあるwebサーバが戻すJSONをパーズしたらエラーになった。
原因はレスポンスのJSONをStringインスタンスにしたときに末尾にNUL(\0)文字が付加されていたため。
JSON仕様ではオブジェクトの後ろにホワイトスペース以外の文字があるときに不正なJSONとして扱う。
ホワイトスペースは \t, \n, \r, 半角スペースである。
NUL (\0) 文字はホワイトスペースではない。
よって、下記の例のように Gson#fromJson() が "{ \"value\":\"abcd\" }\0" をパーズすると
com.google.gson.stream.MalformedJsonException: Expected EOF near
例外が起こる。
package foo; import com.google.gson.Gson; public class App { public static void main( String[] args ) { Gson gson = new Gson(); String json1 = "{ \"value\":\"abcd\" }"; String json2 = "{ \"value\":\"abcd\" }\0"; System.out.println("json1.length():" + json1.length()); System.out.println("json2.length():" + json2.length()); try { MyClass mc1 = gson.fromJson(json1, MyClass.class); System.out.println("mc1.getValue():" + mc1.getValue() ); } catch (Exception e) { e.printStackTrace(); } try { MyClass mc2 = gson.fromJson(json2, MyClass.class); System.out.println("mc2.getValue():" + mc2.getValue() ); } catch (Exception e) { e.printStackTrace(); } } class MyClass { private String value; public String getValue() { return value; } public void setValue(String value) { this.value = value; } } }
json1.length():18 json2.length():19 mc1.getValue():abcd com.google.gson.JsonSyntaxException: com.google.gson.stream.MalformedJsonException: Expected EOF near at com.google.gson.Gson.assertFullConsumption(Gson.java:478) at com.google.gson.Gson.fromJson(Gson.java:468) at com.google.gson.Gson.fromJson(Gson.java:417) at com.google.gson.Gson.fromJson(Gson.java:389) at foo.App.main(App.java:26) Caused by: com.google.gson.stream.MalformedJsonException: Expected EOF near at com.google.gson.stream.JsonReader.syntaxError(JsonReader.java:1111) at com.google.gson.stream.JsonReader.quickPeek(JsonReader.java:386) at com.google.gson.stream.JsonReader.peek(JsonReader.java:340) at com.google.gson.Gson.assertFullConsumption(Gson.java:474) ... 4 more
参考
- http://stackoverflow.com/q/11484353/2608960
- GSON throws that particular error when there's extra characters after the end of the object that aren't whitespace, and it defines whitespace very narrowly (as the JSON spec does) - only \t, \n, \r, and space count as whitespace. In particular, note that trailing NUL (\0) characters do not count as whitespace and will cause this error.
- http://www.ietf.org/rfc/rfc4627.txt