How to unescape a JSONString?

1,407 views
Skip to first unread message

peterk

unread,
Nov 9, 2009, 5:47:27 AM11/9/09
to Google Web Toolkit
I'm having some trouble dealing with escaping and unescaping of Java
strings for encoding in JSON.

I use JSONString to encode a Java string and that seems to work ok.
For example, newlines turn into \n, tabs turn into \t and so on.

However, given this escaped sequence back, how to I turn this back
into an unescaped javastring wheren \n is turned into a newline and so
on?

If I use stringvalue() on the JSONString it just gives back the same
json encoded string with the \n and \t encoding etc.

Anyone have any ideas? :)

Thomas Broyer

unread,
Nov 9, 2009, 6:25:24 AM11/9/09
to Google Web Toolkit
JSONParser.parse? ;-)

Craig Mitchell

unread,
Apr 6, 2024, 2:01:13 AMApr 6
to GWT Users
I ran into this.  GWT is too smart sometimes.  :)

For my example, I was querying an API for WebRTC ICE servers, which returned a string which was a JSON array.

When I had:

private static native JavaScriptObject createPeerConnection(String iceServersJson) /*-{
  var peerConnectionConfig = {
    iceServers: iceServersJson
  };
  return new RTCPeerConnection(peerConnectionConfig);
}-*/;

GWT excaped the quotes, so iceServers switched from an array, to just a string, exactly like I asked it to.

So, really, I needed what Thomas suggested:

JavaScriptObject iceServersObj = ((JSONArray)JSONParser.parseStrict(iceServersJson)).getJavaScriptObject();

private static native JavaScriptObject createPeerConnection(JavaScriptObject iceServersJson) /*-{
  var peerConnectionConfig = {
    iceServers: iceServersJson
  };
  return new RTCPeerConnection(peerConnectionConfig);
}-*/;

Now I'm telling GWT it's a JSO, and GWT knows not to escape it.

Thomas Broyer

unread,
Apr 6, 2024, 2:20:48 PMApr 6
to GWT Users
There's no escaping. You have a string value, it stays a string value. If its content is JSON representing an array and you want that array, then indeed you have to parse the JSON.

It looks like there's a major misunderstanding about what GWT does with your code, and/or possibly where/when the code runs or something.
GWT "only" translates the Java syntax to JS (and also optimizes everything), and therefore comes with a library of classes that emulates the Java runtime core classes so they can also be translated the same way as your code. JSNI is an escape hatch to be able to "put JS syntax inside your Java syntax", but that's all.
In other words, if you have a string "[ 42, true, null ]" in a variable (that you retrieved from your server), if you call that method, it's exactly equivalent to this JS:
var iceServersJson = "[ 42, true, null ]";
var peerConnectionConfig = {
  iceServers: iceServersJson
};
i.e. the peerConnectionConfig object has an iceServers property whose value is just the iceServersJson string value.
GWT won't "magically" generate JS code at runtime replacing the value as-is to form some new JS each time, i.e. it won't become:
var peerConnectionConfig = {
  iceServers: [ 42, true, null ]
};
No, really, that Java/JSNI function is transformed to this JS function:
function createPeerConnection(iceServersJson) {
  var peerConnectionConfig = {
    iceServers: iceServersJson
  };
  return new RTCPeerConnection(peerConnectionConfig);
}
and then at one point you call it. It's your job to give it either a string value or parse the string value as JSON and passe the result.

Kudos to resurrecting a 15 years old post though! 🤣

BTW, you may want to prefer JsonUtils.safeEval(iceServersJson) here: https://www.gwtproject.org/javadoc/latest/com/google/gwt/core/client/JsonUtils.html (and actually you may want to move to using JsInterop rather than JSNI, and maybe Elemental 2)

Craig Mitchell

unread,
Apr 10, 2024, 5:27:42 AMApr 10
to GWT Users
You weren't kidding.  I checked the compiled JS, and there it is (with some smarts to minimise the JS it looks like):
    this.a = new U2b(d,c,(n = {
        iceServers: m
    },
    new RTCPeerConnection(n)));

Thanks for letting me know about JsonUtils.safeEval(...)  That is a better option.

I never had much luck with JsInterop.  I just tried it again, trying to map the RTCPeerConnection, but it doesn't work giving me "TypeError: Cannot read properties of undefined" when I try to instanciate it.  I also can't debug it, as I can't step into the constructor to see what's going wrong.

This was my failed attempt:

@JsType(isNative = true)
public class RTCPeerConnection {
  @JsConstructor
  public RTCPeerConnection(JavaScriptObject iceServersJsoArray) {
    super();
  }
  public native void close();
}

Craig Mitchell

unread,
Apr 10, 2024, 5:44:08 AMApr 10
to GWT Users
Sorry, figured it out.  I needed a namespace:

@JsType(isNative = true, namespace = JsPackage.GLOBAL)
public class RTCPeerConnection {

  public RTCPeerConnection(JavaScriptObject iceServersJsoArray) {
    super();
  }
  public native void close();
}

Now working great!  🙂

Reply all
Reply to author
Forward
0 new messages