You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by Matthias Kerkhoff <ma...@BESToffers.de> on 2000/11/11 13:28:51 UTC

Some thoughts on / problems with Struts (mostly tag related)

Hello all,

although I'm not really lucky with the subject of this message,
I didn't find anything better. What follows are some thoughts
on and some problems I had/have with Struts.

It's absolutly possible that I'm making some wrong assumptions,
so some of the following points may appear a bit strange, but
it's equally possible, that I'm not the only one stumbling over
these things.
I would appreciate any comments and/or explanations from the more
experienced struts users or developers and hope that everyone
benefits from the discussion.

Thanks in advance
Matthias


Automatic bean creation
-----------------------
I've noticed, that both the struts:form tag and the action servlet
create the form bean if it doesn't exist. Also, the bean's name
and scope can be specified in these two different places ways (in
the action mapping and via attributes of the form tag). I am a bit
confused, if this is really necessary and would appreciate an example
where it makes sense to have both ways.


Multiple select
---------------
The select tag does not fully support multiple selection. As far as I
understand, it's possible to mark it as "multiple", but the select tag
has some references to getScalarProperty that will cause difficulties.
I too don't see, how a select multiple would keep it's selection
state, if the user has made some error elsewhere in the form and
the form get's redisplayed.


form-tags and nested properties
-------------------------------
The form tags don't support nested or indexed properties by default.
I think, that all required code is already present (in PropertyUtils),
however BeanUtils.populate is implemented in a way, that prevents the
use of nested or indexed properties (by assuming that all property
names are names of simple properties). Why ?
Allowing nested or indexed properties could also lead to cleaner code
with multipage forms. Currently, using validate and reset in multipage
forms is a bit clumsy, because one has to clutter the code with
conditionals (like if(step == STEP_1) {...} else if (step == STEP_2){..}
and so) to implement partial validation and partial reset as needed
usually for multipage forms.
Having nested properties, this could easily be implemented by having
one (nested) bean per step and than just forward the validate or reset
to these nested beans.
Another benefit would be, that the multibox tag would become obsolete,
because the only additional functionality it offers are indexed properties.


name attribute in form tags
---------------------------
The name attribute is present in most form tags. The documentation
mentions, that the name attribute (for example in select or in checkbox
can be used to specify a bean, where the property value is query from.
Again, I don't see the reason for this attribute, because the value,
when sent back to the server, will not be set in the bean that served
it originally, but in the form bean.
Furthermore, the (struts) way to use of 'name' is quite confusing.
Most struts attributes names mirror html attribute names, so it's quite
predictable, that the average user will understand this as a general
design principle/naming convention.
However, 'name' completly breaks it and makes it the struts tags quite
difficult to understand (for HTML-designers, and they're usually the
intented users of jsp tags). For example:

- form name=        means a bean name, but is also used as
                    html name attribute;

- select name=      means a bean name, but is _not_ used as
                    html name attribute;

- select property=  means a bean's property and _is_ used as html
                    name attribute;

Although I understand, the technical reasons behind the way _how_ the
struts attributes are used, I would think, that it would be a better
way to choose a different attribute name for concepts not related to
html (like it is done with 'property'). A good solution would be to
name (sic) the attribute 'bean'. That would make it's intention clear
and prevent any confusion with the html name attribute.
Maybe, it would also be a good idea to clearly document _how_ to name
tag attributes that ...
- represent struts-only concepts (like 'forward')
- represent concepts that have a meaning in both struts _and_ the
  generated content-type (like locale, id or name)
- have a meaning only in the generated content type (like 'accesskey')
... and the update the tags to follow these hypothetical guidelines.


Generating id= in the html output
---------------------------------
The struts form tags have no possibility to generate an id= in the
html output. This is one of the W3C's core attributes, ie. one that is
allowed in _every_ HTML tag. I don't understand, why struts doesn't
support it. (see also "Standard HTML attributes" below)


form "method=get" will not work in every container
--------------------------------------------------
Well, this is just one more of the uncountable WebLogic problems I've
found in the last few weeks. It may occur in other containers too, so
I think it's not a bad idea to mention it here.
If URLs are used for session tracking and the form method is set to
get, the session will probably lost. This happens, because some containers
encode the session-id as part of the query string. In get-form's the
browser will replace the query string completly with the one build from
the form fields (in accordance to the HTML4 spec).
A possible solution would be to automatically add a hidden field jsessionid
containing the session id (similar to how focus= is handled). This should
not cause any problems with compliant containers, like Orion, and would
reduce problems with containers like WLS.


styleClass attribute
--------------------
I understand that the CSS class= attribute conflicts with
java.lang.Object.getClass(), but I don't understand, why it's necessary
to introduce yet another new name. Here are two alternative solutions,
that I would favor over styleClass:
a) Ignore the conflict with Object.getClass(). This may be a bit confusing,
   but it is actually not a real conflict, because only setClass() is
   really needed for parsing the tag and setClass is not defined in Object.
b) Solve the naming conflict by using established alternative names. The
   W3C DOM2 spec. faces exactly the same problem and already has designated
   alternative names for attributes that may cause conflicts with
   implementation languages. For example, they resolve the class= to
   an attribute named 'className'.


(defaults) values in form tags
--------------------------------
In the moment, if a value= is present in a struts tag, the actual
property value will be ignored. If value= is not present, the property
value will be taken. I don't like this, because it leads to the fact,
that default values must be hard-coded somewhere in the form beans.
Doing it the other way (using value= _only_ if the property value is
null or empty) would be a much more natural way and would allow to
specify defaults in the JSP page, that are 'overridden' by (any) user
input.


code bloat due to unneccessary extension of BodySupport
-------------------------------------------------------
Nearly all (form) tags extend BodySupport, but only some tags make use
of the features associated with BodySupport. Using BodySupport as a
base class leads to more code in the generated servlet and slows down
the execution. Beside the performance aspect, it could in turn cause
problems on some VMs hitting method size restrictions.


tags that work with collection of presentation things
-----------------------------------------------------
In the moment there are only two such tags. Its the options and the
errors tag. (Missed any?) Both share a common drawback, that forces
the designer to mix html markup into the tags or to not use them
at all. I think that a simple solution exists (see below), that would
make them easier to use and probably would be a good base for more
collection valued tags.

Examples currently not possibe or difficult to achieve:
a) Using fieldset with options. How can one group options into fieldsets?
   This is not possible, the only solution is to use single option tags.
b) Displaying errors in a table or a list with the errors tag
   This is only possible, if the error messages are cluttered with
   HTML markup. Doing so will lead to major problems, if multiple
   content types (like HTML, XHTML, WML ...) must be supported from the
   application (well, there are many other places that too cause major
   problems with multiple content-types...)
c) Grouping error messages
   Say you want to group errors into those, where a value is missing and
   those where an invalid value has been entered. This is not possible
   with the errors tag.

Possible solution:
I would propose three additional arguments (start, end, between), with
the following meanings:
- start
  optional value where to start iterating a collection. If not present
  start at the first element. (Probably a better name would be offset,
  regarding the naming convention of logic:iterator)
- end
  optional value where to end iterating a collection. If not present
  end at the last element. (An alternative would be to specify the
  number of iterations like iterator does.)
- between
  Optional attribute, that contains markup that should be inserted
  between two iterated items. Not inserted before the first and after
  the last element.


Standard HTML attributes
------------------------
_None_ of the struts form tags does support the standard HTML4 attribute
set. Some tags only miss the id attribute, but in most cases their are
serious differences between the W3C specification and the attribute set
support from struts.

This may force users trying to convert existing applications to the
Struts framework to drop their efforts and in turn reduce (or at least
hinder) the overall acceptance of Struts.




Thanks for reading.
Matthias



Re: Some thoughts on / problems with Struts (mostly tag related)

Posted by Pierre Métras <ge...@sympatico.ca>.
Hi

I support most of the points raised by Matthias, as I encountered the same
problems/interrogations. And everyone who have tried to extend Struts tags
or implement forms created by designers have surely encountered them...

> Automatic bean creation !
> Multiple select
> form-tags and nested properties !
> name attribute in form tags !!
If version 1.0 has to be incompatible with version 0.5, now is the time to
take that sort of decision

> Generating id= in the html output !
> form "method=get" will not work in every container
> styleClass attribute !

> (defaults) values in form tags !
I don't apply totally for this one as I don't want to have localised values
stored in forms, even initializations.

> code bloat due to unneccessary extension of BodySupport !!

> tags that work with collection of presentation things !
I would add that the <errors> tag can't be used due to bad design. Solutions
have been suggested for the past months...

> Standard HTML attributes !!
>
> Matthias
>

Pierre Métras



RE: Some thoughts on / problems with Struts (mostly tag related)

Posted by Colin Sampaleanu <ca...@exis.com>.
> -----Original Message-----
> From: Craig R. McClanahan [mailto:Craig.McClanahan@eng.sun.com]
> Sent: Sunday, November 12, 2000 11:03 PM
> To: struts-user@jakarta.apache.org
> Subject: Re: Some thoughts on / problems with Struts (mostly tag
> related)
>
>
> Colin Sampaleanu wrote:
>
> > Keep in mind that it is perfectly ok (depending on how you want
> to design
> > your app) for the user to come in through either the JSP page
> or through the
> > action url.
> >
> > On that basis, you need to be able to specify and create the
> form bean in
> > each of those two places, and those two places don't know anything about
> > each other. The JSP page doesn't know about action mapppings, and the
> > mapping doesn't know anything about all the particular JSP
> pages that may
> > want to use that form. There is not even any stipulation that a
> form used in
> > a JSP page has to be used in a mapping, e.g. the submit from
> the form could
> > theoretically go to any URL. The inverse also applies.

As long as it can still handle the case where the action is not going to any
particular mapping at all, and let's you specify the right values...

> Your reasoning on why it needs to be created in either place is correct.
>
> What's still screwed up in the current design is that you have to
> specify the
> bean class and scope in two places (the page itself and the configuration
> file).  Ideally the form tag should be smart enough to look up
> the right action
> mapping (based on where it's going to submit to) and therefore
> infer the right
> bean class and scope if not specified.  I just haven't gotten
> that far yet.
>
> > As to why the bean is automatically created if it doesn't
> exist, I do agree
> > that there are cases in which you might want to have some sort
> of error if
> > the bean doesn't already exist, but you can easily do that by having a
> > special member variable in the bean that indicates that it has just been
> > created. On a manual create you would reset that yourself, but
> on an auto
> > create it would remain set, and the validate method would
> detect it (or you
> > could check manually).
> >
>
> For testing whether a bean was newly created by the JSP page, a particular
> feature of the <jsp:useBean> tag is useful -- the body of this tag is only
> evaluated when the bean is created.  Consider the following:
>
>     <jsp:useBean id="beanname" scope="session"
> class="com.mycompany.MyBean">
>         <jsp:setProperty name="pageCreated" value="true"/>
>     </jsp:useBean>
>
> In this scenario, setPageCreated(true) will be called if the bean
> was created by
> this page.  If the "pageCreated" property defaults to false, you
> now have an
> easy test.
>
> For general purpose detection of existing beans, the new logic
> tags make this
> easy:
>
>     <logic:notPresent name="beanname" scope="session">
>         You are a bad boy ... the "beanname" bean is missing!
>     </logic:notPresent>
>
I was thinking more on the action handler side, your suggestions are of
course easiest for a JSP page...


Re: Some thoughts on / problems with Struts (mostly tag related)

Posted by "Craig R. McClanahan" <Cr...@eng.sun.com>.
Colin Sampaleanu wrote:

> Keep in mind that it is perfectly ok (depending on how you want to design
> your app) for the user to come in through either the JSP page or through the
> action url.
>
> On that basis, you need to be able to specify and create the form bean in
> each of those two places, and those two places don't know anything about
> each other. The JSP page doesn't know about action mapppings, and the
> mapping doesn't know anything about all the particular JSP pages that may
> want to use that form. There is not even any stipulation that a form used in
> a JSP page has to be used in a mapping, e.g. the submit from the form could
> theoretically go to any URL. The inverse also applies.
>

Your reasoning on why it needs to be created in either place is correct.

What's still screwed up in the current design is that you have to specify the
bean class and scope in two places (the page itself and the configuration
file).  Ideally the form tag should be smart enough to look up the right action
mapping (based on where it's going to submit to) and therefore infer the right
bean class and scope if not specified.  I just haven't gotten that far yet.

>
> As to why the bean is automatically created if it doesn't exist, I do agree
> that there are cases in which you might want to have some sort of error if
> the bean doesn't already exist, but you can easily do that by having a
> special member variable in the bean that indicates that it has just been
> created. On a manual create you would reset that yourself, but on an auto
> create it would remain set, and the validate method would detect it (or you
> could check manually).
>

For testing whether a bean was newly created by the JSP page, a particular
feature of the <jsp:useBean> tag is useful -- the body of this tag is only
evaluated when the bean is created.  Consider the following:

    <jsp:useBean id="beanname" scope="session" class="com.mycompany.MyBean">
        <jsp:setProperty name="pageCreated" value="true"/>
    </jsp:useBean>

In this scenario, setPageCreated(true) will be called if the bean was created by
this page.  If the "pageCreated" property defaults to false, you now have an
easy test.

For general purpose detection of existing beans, the new logic tags make this
easy:

    <logic:notPresent name="beanname" scope="session">
        You are a bad boy ... the "beanname" bean is missing!
    </logic:notPresent>

Craig McClanahan





RE: Some thoughts on / problems with Struts (mostly tag related)

Posted by Colin Sampaleanu <ca...@exis.com>.
Keep in mind that it is perfectly ok (depending on how you want to design
your app) for the user to come in through either the JSP page or through the
action url.

On that basis, you need to be able to specify and create the form bean in
each of those two places, and those two places don't know anything about
each other. The JSP page doesn't know about action mapppings, and the
mapping doesn't know anything about all the particular JSP pages that may
want to use that form. There is not even any stipulation that a form used in
a JSP page has to be used in a mapping, e.g. the submit from the form could
theoretically go to any URL. The inverse also applies.

As to why the bean is automatically created if it doesn't exist, I do agree
that there are cases in which you might want to have some sort of error if
the bean doesn't already exist, but you can easily do that by having a
special member variable in the bean that indicates that it has just been
created. On a manual create you would reset that yourself, but on an auto
create it would remain set, and the validate method would detect it (or you
could check manually).


-----Original Message-----
From: Matthias Kerkhoff [mailto:make@BESToffers.de]
Sent: Saturday, November 11, 2000 7:29 AM
To: struts-user@jakarta.apache.org
Subject: Some thoughts on / problems with Struts (mostly tag related)

Automatic bean creation
-----------------------
I've noticed, that both the struts:form tag and the action servlet
create the form bean if it doesn't exist. Also, the bean's name
and scope can be specified in these two different places ways (in
the action mapping and via attributes of the form tag). I am a bit
confused, if this is really necessary and would appreciate an example
where it makes sense to have both ways.