[json] JSON and escaping characters

I have a string which gets serialized to JSON in Javascript, and then deserialized to Java.

It looks like if the string contains a degree symbol, then I get a problem.

I could use some help in figuring out who to blame:

  • is it the Spidermonkey 1.8 implementation? (this has a JSON implementation built-in)
  • is it Google gson?
  • is it me for not doing something properly?

Here's what happens in JSDB:

js>s='15\u00f8C'
15°C
js>JSON.stringify(s)
"15°C"

I would have expected "15\u00f8C' which leads me to believe that Spidermonkey's JSON implementation isn't doing the right thing... except that the JSON homepage's syntax description (is that the spec?) says that a char can be

any-Unicode-character- except-"-or-\-or- control-character"

so maybe it passes the string along as-is without encoding it as \u00f8... in which case I would think the problem is with the gson library.

Can anyone help?

I suppose my workaround is to use either a different JSON library, or manually escape strings myself after calling JSON.stringify() -- but if this is a bug then I'd like to file a bug report.

This question is related to json unicode

The answer is


This is SUPER late and probably not relevant anymore, but if anyone stumbles upon this answer, I believe I know the cause.

So the JSON encoded string is perfectly valid with the degree symbol in it, as the other answer mentions. The problem is most likely in the character encoding that you are reading/writing with. Depending on how you are using Gson, you are probably passing it a java.io.Reader instance. Any time you are creating a Reader from an InputStream, you need to specify the character encoding, or java.nio.charset.Charset instance (it's usually best to use java.nio.charset.StandardCharsets.UTF_8). If you don't specify a Charset, Java will use your platform default encoding, which on Windows is usually CP-1252.


hmm, well here's a workaround anyway:

function JSON_stringify(s, emit_unicode)
{
   var json = JSON.stringify(s);
   return emit_unicode ? json : json.replace(/[\u007f-\uffff]/g,
      function(c) { 
        return '\\u'+('0000'+c.charCodeAt(0).toString(16)).slice(-4);
      }
   );
}

test case:

js>s='15\u00f8C 3\u0111';
15°C 3?
js>JSON_stringify(s, true)
"15°C 3?"
js>JSON_stringify(s, false)
"15\u00f8C 3\u0111"