1

I have an app that is a mix between a single-page Backbone.js app and a Struts2 server-generated web application. I am aware that this is not exactly standard practice, but it is not in my power to change the architecture.

The application maintains some Javascript models in the client and does stuff with them (what exactly is irrelevant here). In order to change the properties of those models, Struts2-based actions have to be called over XHRs with the models POSTed to the form action using $.ajax with the JSON converted to application/x-www-form-urlencoded by jquery. This will return a HTML fragment representing a form, which can then be filled out by the user and is then converted back into a model using $('form').serializeArray() and a custom transformation step. This has been working okay-ish so far, but now we have models that may contain arrays, for example like this one:

{
    "name": "Jannik",
    "contact_methods": [
        {
            "type": "mobile",
            "phone_number": "+491...."
        }, {
            "type": "email",
            "email": "jannik.jochem@..."
        }
    ]
}

JQuery will convert this to form key-value-pairs like this:

name=Jannik
contact_methods[0][type]=mobile
contact_methods[0][phone_number]=+491....
contact_methods[1][type]=email
contact_methods[1][email]=jannik.jochem@...

I now want to be able to iterate the entries in contact_methods using Struts' taglib or anything else that is available in JSP, but I cannot figure out how to do this. If this is impossible, changing the way the JSON object is converted to and from key/value-pairs is acceptable as well. Note however that the nested objects may have different field combinations, so just mapping the individual fields to array parameters would not work because the array indexes would get messed up.

Is there a way to accomplish this in Struts?

EDIT here's the code (note that this is a constructed example since I cannot post the actual code here due to confidentiality issues):

JSONTestAction:

public class JSONTestAction extends ActionSupport {
}

jsontest.jsp:

<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>

<b>Parameters:</b><br>
<pre>
<s:property value="#parameters"/>
</pre>

<b>Contact methods:</b><br>
<ol>
<s:iterator value="#parameters['contact_methods']">
    <li><pre><s:property/></pre></li>
</s:iterator>
</ol>

Backbone view snippet:

var model = {
    "name": "Jannik",
        "contact_methods": [
        {
            "type": "mobile",
            "phone_number": "+491...."
        }, {
            "type": "email",
            "email": "jannik.jochem@..."
        }
    ]
};
$.ajax({
    url: contextRoot + '/properties_jsontest.action',
    type: 'POST',
    data: model,
    success: function (data) {
        var form = $('<form id="element-form" role="form"></form>');
        form.appendTo(view.$el);
        form.html(data);
    }
});

The result is this:

Parameters:
{contact_methods[1][type]=[Ljava.lang.String;@5e2d7ab9, contact_methods[0][type]=[Ljava.lang.String;@7bd437fc, name=[Ljava.lang.String;@29a7c0e7, contact_methods[1][email]=[Ljava.lang.String;@4469930e, contact_methods[0][phone_number]=[Ljava.lang.String;@6f359f38}
Contact methods:

I want to iterate over contact_methods inside the JSP.

Roman C
  • 49,761
  • 33
  • 66
  • 176
Jannik Jochem
  • 1,516
  • 1
  • 14
  • 28
  • 1
    Maybe this will help you - http://stackoverflow.com/q/27828138/1700321. – Aleksandr M Mar 19 '15 at 09:39
  • 1
    Nice, this did not turn up during my Google search. I'll give this a shot. Thanks! – Jannik Jochem Mar 19 '15 at 09:41
  • Using the format `contact_methods[0]['type']=mobile` does not make a difference, struts still treats the key-values as individual request parameters. Sending a JSON entity instead does not seem to work either - doing this, I end up with empty `#parameters`. – Jannik Jochem Mar 19 '15 at 11:04
  • Not sure what do you mean now. You want to send values from page to action, right? Which individual request parameters are you talking about? And what is `#parameters`? – Aleksandr M Mar 19 '15 at 11:17
  • I want to send JSON data from the browser to the JSP page that is invoked by the action, ideally without having to change anything about the action. `#parameters` is the variable that contains the request parameters (query parameters and posted form data) from the request. I'm not sure if this is standard struts or something specific to the system I'm working on. – Jannik Jochem Mar 19 '15 at 12:32
  • Maybe you can show some code, because it is very confusing (to me at least). – Aleksandr M Mar 19 '15 at 13:13
  • It is not required to get a power to change the architecture, unless you get the power to rewrite it from scratch, but this process is time consuming and can introduce new bugs that have unpredictable side effects. You'd better start learning a technology stack that will let you to get solutions to your problems. Because you are doing something wrong and without code it's impossible to point you on your errors. – Roman C Mar 19 '15 at 14:41
  • What exactly are you trying to tell me? – Jannik Jochem Mar 19 '15 at 14:43
  • Well you are doing it the wrong way. The `#parameters` is a map and a `contact_methods[1][type]` is a string key in this map. W/o action code it is very hard to help any further. – Aleksandr M Mar 19 '15 at 18:37
  • So what would the action have to do in order to expose the JSON structure to the JSP? – Jannik Jochem Mar 20 '15 at 09:17
  • 1
    If you are returning json from the action then you can process it in javascript. To be able to use taglibs expose your model as objects. – Aleksandr M Mar 20 '15 at 09:33
  • That's what I was hoping to avoid. Life could be so easy with a sane web framework. Well, thanks for your help. – Jannik Jochem Mar 20 '15 at 12:30
  • So you are sending values to server side and don't have a objects to which those values will be mapped? How are you processing those values on server side then? – Aleksandr M Mar 20 '15 at 14:11
  • I don't have Java objects, no. I just need to render some HTML based on the submitted values (without a lot of business logic). Basically, the only reason why I have to talk to the server at all is because the frontend guys need their templates. The JSON will eventually be processed by a service which takes the JSON out of a database, but exposing that service's internal objects to the web layer would introduce unwanted coupling between modules. – Jannik Jochem Mar 20 '15 at 14:52
  • @JannikJochem: Interesting... How about exposing `JSONObject` (if you are using json.org implementation) , then you can call its methods from the jsp. http://stackoverflow.com/q/22110439/1700321. – Aleksandr M Mar 20 '15 at 18:58

0 Answers0