Adam Hardy wrote:
Laurie,

my chosen option would be to use your view objects as form objects, where you modify the view object by adding string-typed getters and setters for every property.

I'm not really keen to 'pollute' the view objects with String-type derived properties just for the HTML presentation; the view objects are how any client (web app, web service, Swing GUI, etc) would interact with the application. This also implies having String-to-model conversion code scattered through the view objects...


I don't really get what you mean in your (2).

This is what I decided to try first. I threw together a prototype last night, and it seams to work well. Basically, the idea is:


- extend the view API to include 'View.toMap(Map props)' and 'void View.fromMap(Map props)' on each view class

- you can then do view.fromMap(form.getMap()) and view.toMap(form.getMap()) to translate between views and form beans

- add a custom tag which takes a form bean and a view and loads the form's map from the view (I've implemented this so it can lookup the form bean from an enclosing <html:form/> tag, so you only have to pass in the view)

Now, my JSPs can do something like this:

<jsp:useBean id="view" class="MyViewBean"/>
... setup view (e.g. populate from db) ...
<x:loadForm view="${view}"/>

Now, the form bean associated with the enclosing form is populated from the view object. On subsequent page loads, I can skip the loadForm tag, and the form bean has the data from the previous submission.

I still need to do some more testing, but this seems to be working nicely.

I think the parameter handling issue is hugely debatable. I've lost count of the number of discussions I have had about it.

Yeah, lots of options here :-)

Alot depends on where you get your view objects from. Are they the data transfer object pattern?

Roughly, yes. There's a 'service layer' that interacts with the domain model (business objects). It returns view objects which are POJOs containing the state from the business objects but not the behaviour.


Whatever, try to keep it as simple as possible.

Always good advice! The trick is remembering who to keep it simple for, me or the end user ;-)


L.


Adam

On 18/05/05 20:45&nbsp;Laurie Harper wrote:

[Appologies for the long post; hopefully it'll spark some interesting
discussion though.]

Does anybody develop with Struts using a 'pull' model (where JSPs 'pull'
in the data they need, rather than having it 'pushed' to them by a
calling action)? I've been doing this successfully for some time with
applications that only use forms for capturing new data, no editting of
existing data. Now that I come to add the ability to update existing
data to an application, I've hit a limitation in my design. I'm hoping
others have encountered the same issue, or have suggestions for dealing
with it.

Here's the problem: I generally have a JSP for capturing new data, which
will use a DynaActionForm to manage the form inputs through multiple
edit-validate cycles until the form data is accepted and committed to
the database. For display of existing data, a different JSP is used
which 'pulls' the data in (using a custom tag or by instantiating a
bean). This JSP is fronted by a simple ActionForward. The page renders
the data as pulled from the database. For the sake of simplicity, assume
this 'pull' step puts a POJO bean into some scope (request usually);
call this the view object.

Now, if I want to be able to edit that data, the form needs to render
the data from the view object the first time it loads, but from the
ActionForm instance on subsequent loads (after validation fails). The
submit action, when it succeeds, then rebuilds the view object from the
form data and submits it to the service/domain layer via a 'store'
operation.

Note that there is no custom action to populate the form bean; form data
is pulled by the JSP page for editting just as for display. The reason
for this is that it should be possible to build new forms/pages without
modifying Java code. That's a basic requirement for this application.

So, the question is, how do I (a) populate the form bean from the JSP
and (b) determine when to do so? Some options I've considered:

1) write a custom tag that looks up the form bean and view object in the
appropriate scope and uses BeanUtils.describe() or some other method to
fill out the form bean; this would probably require the view objects to
expose a describe() method returning a Map since view objects represent
structured data (a view object may have properties that are themselves
view objects)

2) write a 'form manager' bean JSPs can use to say 'populate this form
bean with data from this view object'. The form bean manager then does
the work that is usually done in actions in the traditional 'push'
model. To avoid excessive coupling, a describe() method on the view
objects would be a good idea (otherwise the manager class would have to
know the view -> form bean mapping rules for every view object and form
in the system).

3) always render the form using the view object and have the submit
action update the view object with the form data before validating. This
wont work since view objects have typed properties and I wouldn't be
able to 'round trip' invalid inputs (the same reason form beans usually
only use String properties).

4) seperate create, edit and view operations into different JSPs. Appart
from the duplication of markup that introduces, it only helps for the
create (always use the form bean) and view (always use the view object)
cases; edit is still 'broken'.

I'm leaning toward the form manager (option 2) so a JSP might look like:

<jsp:useBean var="view" class="..."/>
<jsp:useBean var="mgr" class="...FormManager"/>
<jsp:setProperty name="mgr" property="form" value="${the form bean}"/>
<jsp:setProperty name="mgr" property="view" value="${view}"/>

The form manager would take an instance of DynaActionForm and update its
map of properties from the view. (I'm assuming the form bean is mutable
in this way!) I'd still need to know when to invoke the form manager I
suppose, but that's easier to solve with a request parameter or other
'state' tracker.

Anyone got any better approaches?

L.


---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to