PDA

View Full Version : JSON Nesting, CRUD and Form Beans



mrjoltcola
14 Oct 2009, 6:24 PM
I've been using Ext JS with Struts2 for well over a year successfully, but mostly on read-only JSON results.

Now that I am adding full CRUD APIs to my app, using either Ext.form.Action.Submit (http://www.extjs.com/deploy/dev/docs/output/Ext.form.Action.DirectSubmit.html) or Ext.data.HttpProxy, I have a problem. I use Struts2, and I serialize my server side results in a bean. So instead of 40 fields for a Patient record, they are nested inside the patient bean. Problem is, submitting them back with the same API gives me no way to preserve the nesting.

The docs say to return results to the Form Load action like this:

{
success: true,
data: {
clientName: "Fred. Olsen Lines",
portOfLoading: "FXT",
portOfDischarge: "OSL"
}
}

That's fine. The problem is, the Form Submit action doesn't post the JSON back as data.*, it passes all of the attributes back unqualified. Something is non-orthogonal here. Either the API, or my understanding of it.

It is easy enough to use the "root" config param with a JSON reader, but I see no similar param when writing JSON back. I simply want to prefix or wrap the JSON packet so it goes back to my server with the same nesting that I received it. Since this is how the JSON plugin for Struts2 works, about the only other option I see is to use the actual Action bean as the root of my serialization, and I do not like that idea because I would rather use my domain objects that are already written. I don't want to make this a Struts2 issue. If I pass data one way, it would seem to preserve the name qualification in both directions.


I described using the Form above, but I also have the same issue using Ext.data.HttpProxy and the ony way I could workaround it using Struts2 was to use wrapPrefix and wrapSuffix like so:


<resultname="dataSuccess"type="json">
<paramname="root">extGridData</param>
<paramname="wrapPrefix">{"extGridData":</param>
<paramname="wrapSuffix">}</param>

</result>


Help. I need some suggestions.

Thanks,
mjc

evant
14 Oct 2009, 7:01 PM
I don't know anything about writing Java web apps, however the form submission in Ext is the same as a normal HTTP form post. How does your server side handle that?

mrjoltcola
14 Oct 2009, 8:08 PM
I'm talking about POST of JSON content, and the nesting of the JSON object. Its not an issue of handling a POST of a form.

My point is that the Ext framework includes several components that are 2-way (reader & writer) AJAX components. So if I'm handling a form, I would like to handle it the same way reading and writing.

So according to the Ext docs, my retrieve action must put the form elements in the "data" object. So I do this:

{
"data":{"SSN":"111222233","birthDate":"1967-02-22T00:00:00","firstName":"SARAH","lastName":"SNIDER","zip":"10022"},
"success":true
}


The Form expects the data in that format. However, when it posts via AJAX, the JSON loses the "data" nesting and goes back as:


SSN 111222233
birthDate 1967-02-22T00:00:00
firstName SARAH
lastName SNIDER
zip 10022


I would expect to have the ability to POST it as:

data.SSN 111222233
data.birthDate 1967-02-22T00:00:00
data.firstName SARAH
data.lastName SNIDER
data.zip 10022

Since this example uses JSON to read but a plain HTTP form to post, let me give the example with JSON both ways.


The problem is even more clear when using the HttpProxy with a JsonReader for an editable grid.



var proxy = new Ext.data.HttpProxy({
api: {

read : 'rxProfileRetrieve.emr',
create : 'rxProfileCreate.emr',
update: 'rxProfileUpdate.emr',
destroy: 'rxProfileDelete.emr'
}
});



var reader = new Ext.data.JsonReader({


totalProperty: 'total',

successProperty: 'success',
idProperty: 'id',
root: 'extGridData.entries'
}, [
{name: 'id'},
{name: 'drugDesc', allowBlank: false},
{name: 'symptomDesc'},
{name: 'prescriberName'},
{name: 'rxNum'},
{name: 'fillDate'},
{name: 'qty'},
{name: 'qtyPerDay'},
{name: 'refillDate'},
{name: 'newRxDate'}
]);





var writer = new Ext.data.JsonWriter({

encode: true,

writeAllFields: true,
listful: false
});




The JSON for retrieve is:


{"extGridData":{"entries":["{\"id\":\"1\",\"drugDesc\":\"Xanax - 0.25mg\",\"symptomDesc\":\"Anxiety\",\"prescriberName\":\"Dr. Joe Smith\",\"rxNum\":\"1230011\",\"fillDate\":\"\",\"qty\":\"45\",\"qtyPerDay\":2,\"refillDate\":null,\"newRxDate\":\"\"}"],"selectedId":null,"selectedObject":null}}


But the Grid / HttpProxy serializes it back out as:


{"entries":["{\"id\":\"1\",\"drugDesc\":\"Xanax - 0.25mg\",\"symptomDesc\":\"Anxiety\",\"prescriberName\":\"Dr. Joe Smith\",\"rxNum\":\"1230011\",\"fillDate\":\"\",\"qty\":\"45\",\"qtyPerDay\":2,\"refillDate\":null,\"newRxDate\":\"\"}"],"selectedId":null,"selectedObject":null}



Where is "extGridData" top level node? It is not there, because I'm using "root" node of "extGridData.entries" and there is no way to easily wrap it with "extGridData" on the way out with the JsonWriter. So its not a Java server-side issue. It's an issue of not being able to preserve the nested structure of the JSON object graph properly with the Ext API. I serialize and deserialize to and from the same object, so having the top node discarded is problematic.


Thanks,


mjc

PS: Sorry for the poor formatting, this forum editor is not friendly about preserving things.

leizz
14 Dec 2010, 12:49 PM
Hi mrjoltcola,

I'm interested in your solution to this issue. Do you mind sharing it?

thanks,
leizz