Search code examples
javascriptjsonstrutsjavabeans

Trying to generate table from JSON file with bean tags embedded in HTML


I am trying to generate a table of data from a JSON file using Javascript but am having difficulty because of the bean:write tag. The bean: is getting removed, so only <write name="offenderCountVO" property="addressCount"/> seems to be getting parsed. Is this approach even feasible?

From the page that generates the table:

        // Build profile section from JSON file
        $.getJSON('<%=request.getContextPath()%>/jsp/json/offenderProfileJSON.jsp', function(data) {

            //alert('loading JSON');

            var items = [];
            var table = $('<table class="profile"><\/table>');
            var profileCols = 2;
            var td = "";

            // Build array of profile categories   
            for (i = 0; i < data.length; i++) {
                //alert("building items");

                // Check if this category can be displayed in this module
                var item = data[i];
                var modules = item["modules"];

                //alert("Start check");
                if (modules.indexOf(appName) > 0) {
                    // This category should be displayed
                    //alert ("Passed");
                    var label = item["label"];                  
                    var link = item["link"];
                    var name = item["name"];
                    var property = item["property"];

                    newCategory = { label: label, modules: modules, link: link, name: name, property: property };

                    items.push(newCategory);
                }
            }

            // Alphabetically sort categories by label

            //alert(items.length);
            for (i = 0; i < items.length; i++) {

                html =  '<tr><td><a href="<%=request.getContextPath()%>/' + items[i].link + '">' 
                        + items[i].label + '</a></td><td>\u003Cbean\u003Awrite name="' 
                        + items[i].name + '" property="' + items[i].property + '" /\u003E</td></tr>';       


            }

            $("#testArea").html(html);

            //table.appendTo("#testArea");

            alert("Done");

        }).error(function() {
            $("#testArea").html('<span class="error">Error parsing JSON.</span>');
        });

The JSON file:

[
{
    "label"     :   "Address",
    "modules"   :   "AGNT,BOOKING,DIO,OMP,OTA",
    "link"      :   "offenderAddress.do?method=list",
    "name"      :   "offenderCountVO",
    "property"  :   "addressCount"
},
{
    "label"     :   "Assessments",
    "modules"   :   "AGNT,BOPP,OMP,OTA",
    "link"      :   "offenderAssessmentList.do?method=list",
    "name"      :   "offenderCountVO",
    "property"  :   "assessmentCount"
}       

]

I hope I've explained the issue well enough -- I'm working on several different projects and my head is spinning right now, so let me know if you need any clarification. Any guidance would be appreciated.


Solution

  • <bean:write> is a tag understood by JSP on the server-side, at the point when the initial page is created.

    Using:

    '<td>\u003Cbean\u003Awrite name="'+ items[i].name + '" property="' + items[i].property + '" /\u003E</td>'
    

    from JavaScript makes no sense because the web browser that includes the resultant <bean:write> tag in its page DOM doesn't know anything about Java or bean tags. When the browser's HTML parser sees <bean:write> it thinks only "that's some write tag that I don't know about, spelled funny" and not "I had better ask the server-side what it's value for the property of that bean is".

    If you want the browser to see the server-side value of a variable, you must return that value itself in the JSON response to the browser, not just a name and value pair that only mean anything to the bean-based server side.

    Note also that dropping unescaped strings into HTML markup is dangerous. Without HTML-escaping, you have cross-site-scripting security holes when any of the item values may contain user-submitted values. Use DOM-property methods to set element text and attribute values instead of trying to create HTML markup strings from JavaScript. eg:

    <input type="hidden" id="contextPath" value="<c:out value="${pageContext.request.contextPath}"/>"/>
    ...
    var cp = document.getElementById('contextPath').value;
    
    for (var i= 0; i<items.length; i++) {
        table.append(
            $('<tr>').append(
                $('<td>').append(
                    $('<a>', {href: cp+'/'+items[i].link, text: items[i].label})
                )
            ).append(
                $('<td>', {text: items[i].value_of_whichever_property_it_is})
            )
        );
    }