5

I got this servlet which creates JSON data and I want to pass this data on to a jsp page which is supposed to display the data via the InfoVis toolkit.

servlet.java

JSONObject json = new JSONObject();
    JSONArray toplevel = new JSONArray();
    JSONObject sublevel;

    try{

        json.put("id", "node" + 0);
        json.put("name", "name" + 0);

        int count = 5;
        for(int i=1; i < count; i++){
            sublevel = new JSONObject();
            sublevel.put("id", "node" + i);
            sublevel.put("name", "name" + i);
            toplevel.put(sublevel);
        }
        json.put("children", toplevel);
    } catch (JSONException jse) {

    }

    request.setAttribute("jsonString", json.toString());
    RequestDispatcher dispatcher = request.getRequestDispatcher("graph.jsp");
    dispatcher.forward(request, response);

The following Code is provided by the InfoVis Toolkit and I'm not sure if it can be changed. Or at least I don't have enough experience in JS to change it.

graph.jsp

<body onload="init('${jsonString}');">

spacetree.js

function init(jsonString){

    var json = jsonString;

Originally the function call is only

<body onload="init()">

but the init() function has the JSON variable hardcoded, which is of course not useful at all. So I'm looking for a way to make that dynamic. But since theres quotations inside the string it now totally messes up the onload=init() function call..

PogoMips
  • 3,497
  • 8
  • 27
  • 34

2 Answers2

7

The cheap and easy way is to modify the JSP so it outputs this:

<script>
var theData = ${jsonString};
</script>
<body onload="init(theData);">

The downside to that is that it creates a global variable, but if you're calling init in that way, init is already a global, so that ship has sailed. :-)

T.J. Crowder
  • 1,031,962
  • 187
  • 1,923
  • 1,875
  • Alright, it seems to be passed on correctly. Now I just have to figure out how to get it into the local var in init(). this seems not to work: var json = jsonString; and neither does this var json = String(jsonString); – PogoMips Jan 29 '13 at 19:35
  • 1
    @PogoMips his code passes the object as the parameter to the "init" function. – Pointy Jan 29 '13 at 19:38
  • Ah yeah, noticed that in the debugger too. thanks, that solves it :) – PogoMips Jan 29 '13 at 19:46
  • 1
    +1 for not only the answer but also for the "that-ship-has-sailed" chortle. – Rob Kielty Mar 18 '14 at 16:39
3

You don't have to drop the JSON as a string - it's valid JavaScript syntax:

<body onload='init(${jsonString})'>

When that's rendered by JSP, the end result — the HTML sent to the browser — will be something like:

<body onload='init({"something": "some value", "whatever": "your data looks like"})'>

Now the only thing you may want to do is HTML encode the JSON, since you're dropping it as an HTML attribute value:

<body onload='init(${fn:escapeXml(jsonString)})'>

Then your "init" function can expect a ready-to-use JavaScript object, with no need to call a JSON parser at all.

Pointy
  • 405,095
  • 59
  • 585
  • 614
  • And if the JSON is, say, `{"foo": "It's messed up now"}`? :-) The `'` in `it's` will terminate the `onload` attribute... – T.J. Crowder Jan 29 '13 at 19:27
  • @T.J.Crowder yes I just added the part about HTML encoding it :-) – Pointy Jan 29 '13 at 19:27
  • @ Pointy: Will that encode single quotes? You may want to switch to doubles for the attribute delimiter, I'm sure it must encode those... – T.J. Crowder Jan 29 '13 at 19:28
  • @T.J.Crowder I *think* it will; I do most of my work in JSP so I should know, but I also don't set up "onfoo" event handlers anymore so I'll check. – Pointy Jan 29 '13 at 19:28
  • +1 in any case. I'm always nervous about line breaks in attributes (in case the JSON has line breaks), but I understand they're totally fine, just me be irrational. :-) – T.J. Crowder Jan 29 '13 at 19:29
  • @T.J.Crowder one of the most mind-expanding things about answering questions on SO is having to provide solutions in situations I would never find myself in due to such built-in boundaries. So many times I want to answer a question by suggesting that a person throw it all away and start over :-) You probably know that even better than I do. – Pointy Jan 29 '13 at 19:34
  • @Pointy, I'd love to do that. I don't like this way either. but actually, I usually program in C on microcontrollers. So I have neither the experience in JS nor the time to learn it from scratch now. But I got assigned to this task and I try to do my best with my basic skills ^^ – PogoMips Jan 29 '13 at 19:40
  • @PogoMips don't worry, you're not doing anything horrible here :-) I don't use in-HTML event handlers but there's really nothing *wrong* about it. – Pointy Jan 29 '13 at 19:53
  • 2
    @T.J.Crowder verified that `fn:escapeXml()` always escapes both single- and double-quote characters. – Pointy Jan 29 '13 at 20:03