Excellent!

Michael Oliver
AppsAsPeers LLC
7391 S. Bullrider Ave.
Tucson, AZ 85747
Phone:(520)574-1150
Fax:(520)844-1036


-----Original Message-----
From: Erik Hatcher [mailto:[EMAIL PROTECTED]] 
Sent: Thursday, January 09, 2003 11:32 AM
To: [EMAIL PROTECTED]
Subject: [jug-discussion] Web frameworks (was: Re: [jug-discussion]
January Presentation)

On Thursday, January 9, 2003, at 01:03  PM, Drew Davidson wrote:
> Erik Hatcher wrote:
>
>> On Thursday, January 9, 2003, at 02:01  AM, Tim Colson wrote:
>>
>>> Plus... I don't use JSP anymore, just Velocity templates + Struts.
>>>
>>> So the view in my webapp wouldn't be this:
>>> <%= request.getSession().getAttribute("count") %>
>>
>>
>> And (and I think I e-mailed Drew this a while back too), a seasoned 
>> Struts developer wouldn't use scriptlets anyway.  I would do this:
>>
>>     <bean:write name="count"/>
>>
>> instead.
>
> Yes, this is true.  What you have done demonstrates a couple of other 
> bad things about JSP and Struts.  Where is "count"?  It is in the 
> search path of { request, page, session, context} of course!  It's up 
> to you to guess, of course, if you are reading someone else's code.  
> Or you can grovel all the source code that may have forwarded to this 
> page and see where it sticks it, or you could rely on your 
> organization's "conventions" about where this should be placed...well 
> I hope you get the point.

We use conventions.  Just to be petty, the order is {page, request, 
session, application} (page and request were reversed in Drew's 
comment).

But yup, right.


>> And my hyperlink would be:
>>
>>     <html:link page="/count.do">increment</html:link>
>>
>> Or it could be even cleaner expressed as:
>>
>>     <html:link forward="count">increment</html:link>
>
> So you have had to
>
> (1) come up with a name for an action AND a forward, uniquely across 
> ALL applications running in this context :

All applications?  Well, the Struts Way would be to only have a single 
application within a WAR, at least that is how I do it.  Struts 1.1 now 
had the concept of "modules" where you can have multiple configuration 
files and paths in there are relative to the module and aren't "global" 
per se.

Ugly, yes.  I don't use modules - use multiple WAR's for different 
applications - that separates J2EE security too, and allows deployment 
to different application servers.

> (3) figure out the ONE location that this count will be allowed to 
> forward to - whatever the mapping is of the "success" forward.  You 
> cannot just allow it to redisplay the same page (does returning null 
> do this?  I don't know)

Returning null indicates the Action has completely handled the response 
(i.e. it could server up an image or binary file).  So returning null 
generally would return a blank page if you haven't written anything in 
that action.

An Action can forward to any number of forwards, and they could be 
defined dynamically.  You have to return an ActionForward instance, but 
that could
point to any URL (if its a redirect) or any context URL if its a 
server-side forward.

> (4) Write the struts-config.xml entries for your "count.do" action and

> the action mapping, plus figure out where the forwards go.

Again, XDoclet to the rescue.

XDoclet generates my JSP pages from a form bean definition.  So I write 
a form bean, generate the starter JSP, and then XDoclet generates my 
form bean definitions.  We currently code the action mappings by hand, 
but thats because I think putting them in @tags is lame.

> By this time, in WebOGNL, I have written:
>
> <ognl:hyperlink action="[:[ session.count = session.count + 1 
> ]]">click me</ognl:hyperlink>
>
> ...and moved on to more stimulating things than writing what amounts 
> to (conservatively) 30 lines of code to INCREMENT A COUNTER, when 1 
> expression would do.

Excellent example Drew.  I really appreciate you taking the time to 
carefully explain this with code.  This is very helpful in my 
understanding.

How would you do it without putting <ognl:*> tags in the template, and 
put the code in Java?

>> Of course WebOGNL is much more like WebObjects, which I *love*!  So 
>> WebOGNL has a big architectural jump on the hacked thing we call 
>> Struts (I'm allowed to say its a "hack" because I'm intimate with it,

>> but I use it exclusively at my day job).
>
> I'm allowed to say it's a "hack" because IT IS A HACK :-)

No argument from me here, not at all.

> I'll put WebOGNL up against any other framework.  Name the problem and

> I guarantee I can do it in WO (a) faster, (b) clearer and (c) with 
> less code.

I love it!  Throwing down the gauntlet!

I want to know in what ways WebOGNL is better than Tapestry.  Thats the 
main information I'm after.

>    + WO component templates can be loaded from anywhere, including the

> filesystem, across the web or from a database.

This is where its at. Big +1 here.

>    - Struts/JSP "component" communication is through ad-hoc methods: 
> either use <jsp:include> with nested <jsp:param> and live with String 
> parameters only or use request/session/page/context attributes to 
> communicate - God help you sort out the "conventions" you will have to

> invent to keep all of this manageable and straight in your head, not 
> to mention maintainable by anyone.

Request scoped stuff is no big deal... no conventions needed here since 
they are short-lived and the action/JSP can be kept in tight 
synchronization.

Session variables we have a WebConstants interface where we define them 
as global statics, and use a package-name prefix construct to keep them 
separate.  Its not too tough, and its maintainable.  Sure, someone 
could go nuts and go around the conventions, but we get CVS commit 
messages via e-mail, and I beat the snot out of developers that do not 
adhere to conventions :))

>    - Validating a form happens in the ActionForm.  You get to return 
> ActionErrors which are normally displayed above the form in a list. 
> What happens when I want to know WHY a particular field failed or if I

> want to draw all erroneous fields with a red triangle pointing at 
> them? Roll your own, that's what.

I suggest, if you want to be as Struts knowledgeable as possible for 
sales pitches, that you check out the ValidatorFramework and the 
XDoclet work I've done.  If I want a field in a form bean to be 
required, I simple do this (my forms extend from ValidatorForm, not 
ActionForm directly):

        /**
         * @struts.validator type="required"
         */
        public void setField(String field) { ... }

voila... that field is now a required field.  Likewise with any of the 
builtin Validator validations (date, credit card, etc).  There are tags 
for all features of the Struts Validator pieces.  If you could see the 
hideous XML that this generated, you'd cry.  But a lot of Struts 
developers are writing that crap by hand.

As for flagging fields in error, I wrote LabelTag:

        <custom:label key="FormName.formField"/>

That generates the field label, turns it red if there was an error on 
the field (Validator names the ActionErrors keys by the field name, 
thankfully) and puts an asterisk by it if it is a required field (the 
Validator information is accessible and easily checked for whether a 
field has the required validation set on it, as shown above with the 
@tags.

To see this in action, check out my project:

        http://www.ehatchersolutions.com/JavaDevWithAnt

Its got minimal Struts in it, but all the XDoclet and LabelTag magic is 
hidden within it.  So, while this is not an application that has much 
of a web interface, the build and XDoclet stuff is really what's being 
showcased.

> As for Tapestry, I think that Howard is doing a great job.  He's got 
> the right idea architecturally and the upcoming Tapestry 
> implementation (2.4) will go a long way toward making it greater still

> (with more accessible templating).  Tapestry uses OGNL for bindings, 
> also :-)

So why is WebOGNL better?  Why not combine efforts?

Do you expect (or care if) WebOGNL gains popularity?  Is that the goal, 
or is it just a fun project for you to use on your own projects?  I'm 
just trying to get a feel for where you are going with WebOGNL... are 
you trying to usurp Tapestry/Struts?

        Erik


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



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

Reply via email to