You are viewing a plain text version of this content. The canonical link for it is here.
Posted to user@struts.apache.org by Pierre Métras <ge...@sympatico.ca> on 2000/11/23 16:41:30 UTC

Moving from 0.5 to 1.0: an experience

Hi,

This post is quite long but it traces the situations I encountered when
moving from Struts version 0.5 to 1.0Beta. I hope it can be of help for
others having to do the move.
It took me 2 days to port a small application (46 java, 20 jsp files)
clearing sometimes the code to benefit from new features when I was
debugging a file. I have some work left to check that all features are
running like before, but I think the most tedious part of the work is gone.

Pierre Métras

PS: I include my version of LinkTag.java to support JavaScript events, too.
Though not HTML 4.0 conformant, I hope it will find a path in version1.0;-)


~~~~~~~~~~~~~From 0.5 to 1.0B~~~~~~~~~~~~~~~~
Binaries
=====
- Download tomcat 3.2B7
- Download Struts 2000-11-20
- Susbtitute to existing files and directories.

Java files
======
ActionForm beans
-------------------
- Change "class X implements ActionForm" to "class X extends ActionForm".

- Change "class X implements ValidatingActionForm" to "class X extends
ActionForm".

ValidatingActionForm beans
-----------------------------
- Change "import org.apache.struts.ValidatingActionForm" to "import
org.apache.struts.ActionForm".

- In validating classes, change "validate" method to return an ActionErrors
instead of String[]. Clean the code accordingly. Add "import
org.apache.struts.ActionErrors; import org.apache.struts.ActionError;"

On ActionForm
- Change checkboxes processing in "reset" method. Usually, just set to null
the corresponding property.

- Add reference to ActionMapping for "reset" method: "import
org.apache.struts.ActionMapping".

Action
-------
- Class "ActionBase" is now deprecated. Change to "Action"

- Change "MessageResources resources = getResources(servlet);" to
"MessageResources resources = getResources();". This change could have been
flagged deprecated to ease the transition...

- "ActionMapping.getInputForm" is now deprecated. Use "getInput" in place.

- "BeanUtils.getPropertyValue" changed to "PropertyUtils.getProperty".

- "ActionMapping.getFormAttribute" changed to "ActionMapping.

- ATTENTION: "Action.perform" has lost its servlet argument. If you miss the
change, your source will compile but your "perform" method will never
called! The symptom: an empty page in your browser. The old "perform"
signature should at least exist with a deprecated signal to ease the
transition form 0.5 to 1.0 code.

- The code can be cleaned here with the new classes and methods ActionError,
ActionForm.reset...
For instance, if you have a menu Action class, the perform method will only
have to do the switch to return the mapping. You don't need anymore to
retrieve ActionForm instance attributes (was it from session or from
request?) and initialize their fields (and don't forget to set the attribute
again): all this can be done in one place, the ActionForm.reset method.


First run
======
At that point, everything compiles. Copy the class files to the server.
Start Struts. Wow, there's new traces while the action.xml file is
processed.

- 404: /index.jsp not found!
OK. Right access on directory tomcat/work is not set properly.

- org.apache.jasper.compiler.CompileException: Attribute onMouseOut invalid
according to the specified TLD
<struts:link> has not yet been modified to include JavaScript events
handlers (I have to modify the TLD file a generate a personalized
struts.jar). Hope this will be done in final v1.0.

It couldn't have run at the first shot. Ok, now let's look at the JSP...


JSP
----
- Change <%@taglib uri="struts" prefix="s" %> to <%@taglib uri="struts-form"
prefix="sf" %>, etc.

- Update <s:tags> to the appropriate <sf:tag> or <st:tag> or <sl:tag>...

- Change every JavaScript event handler to use lower case: "onMouseOut"
becomes "onmousout" now! Mama mia...
    <s:message />            <sb:message>
    <s:link> </s:link>        <sf:link> </sf:link>

- org.apache.jasper.compiler.ParseException: Unterminated user-defined tag:
ending tag </sf:link> not found or incorrectly nested
Argh! The LinkTag in org.apache.struts.taglib.form is brand new and
different from the one in org.apache.struts.taglib. Well, I have to patch it
again and regenerate the struts.jar.

- org.apache.jasper.JasperException: Unable to compile class for JSP:
java.lang.NullPointerException
Oops! I forgot to move the LinkTag from "org.apache.struts.taglib" to
"org.apache.struts.taglib.form". Not a really usefull error message from
tomcat!

- Change <s:ifPropertyEquals> to <sl:equal>, </s:ifPropertyEquals> to
</sl:equal>, <s:form> to <sf:form>...
But now with <sl:equal>, an exception is thrown if the value is null. In
version 0.5, <s:ifPropertyEquals> would have returned false... So, don't
forget to enclose the tests in <sl:present> ... Test ... </sl:present>

- Change <s:htmlProperty...> to <sb:write name="" property=""
filter="html"/>
I would suggest using a filter="html", instead of any arbitrary value as
suggested in the documentation, as that will open the door for other
filtering functions (JavaScript escape, WML...).

Great care must be done while renaming tag libraries: if an error is done in
the library prefix, the tag is not interpreted (rendered as HTML text) and
no error is raised.
Well, there's some work here! Unix champions will write a sed script to do
the replacements in the files...

Methodology:
- Check your JSP pages individually to verify that struts tags are correctly
interpreted.
- Then, and only then, go through action url (*.do)...


Action.xml
-----------
- Rename "action.xml" to "struts-config.xml"

- Enable DTD validation: include <!DOCTYPE struts-config PUBLIC "-//Apache
Software Foundation//DTD Struts Configuration 1.0//EN"
"http://jakarta.apache.org/struts/dtds/struts-config_1_0.dtd"> at the top of
struts-config.xml

- Complete change in the syntax, now clearer (in my opinion). Must rewrite
the whole file...

The impact of the new struts-config.xml file should have consequences in the
Java code (in particular, when one change the scope of mappings). But the
features will clear some code...


Web.xml
---------
- References the new taglibs:
    <taglib>
      <taglib-uri>struts-bean</taglib-uri>
      <taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
    </taglib>
    ...

- Change in "action" servlet to reference "struts-config.xml" instead of
"action.xml".

- Enable locale detection. Suppress application tag in every form.
      <init-param>
        <param-name>locale</param-name>
        <param-value>true</param-value>
      </init-param>


Second (well, times later) run
====================
- java.lang.NullPointerException
at
org.apache.struts.action.ActionServlet.processActionPerform(ActionServlet.ja
va:1375)
at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1241)
at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:417)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
etc...

I used to write:
            return new ActionForward(mapping.getInput());
in "Action.process" when I wanted my action to return to the calling form
(partial validation, error...).
Now, the getInput call returns null, instead of the original path, so the
RequestDispatcher in ActionServlet fails to forward the request, and thus
the NullPointerException.
I didn't investigate enough to find if this is now a "normal" feature of
version 1.0. There was a similar bug discussed in the mailing list the 15th
Aug 2000, but it was diagnosed to an action.xml error. I doubled check my
struts-config.xml and it seems correct.

Change it to:
            return mapping.findForward("forwardName")
But don't forget to add the new "forwardName" in struts-config.xml

At least, ActionServlet could protect the call (line 1375 and before) to
check if the mapping has a path != null, just to help debugging.

- ATTENTION: "ActionForm.validate" accepts now two arguments. So my old
validate methods are not called... These too should have been flagged
obsolete.


Last candy
========
During that version evolution, new version 3.2B8 of tomcat and 20001122 of
Struts were released. The tomcat one seems to correct a bug I had with
session management when cookies are not set and Struts added a tag I had
already in my application library. So, let's do the jump again...

- 2000-11-23 10:14:00 - Ctx( /myapp ): Exception in init  Can't happen -
classname is null, who added this ? - java.lang.IllegalStateException: Can't
happen - classname is null, who added this ?

Yahoo! Appart form this slight exception when a picture file is missing, my
application is running now with Struts 1.0. Champagne for everybody!


Some comments and remarks for discussion (perhaps off topic):
===========================================
- If I had used optional imports (import org.apache.struts.*) instead of
explicit ones (import org.apache.struts.ValidatingActionForm), I would not
have to check every files for the new classes. Also, the recompilation
process would have gone quicker because changing "String[] validate()" to
"ActionErrors validate()" would have not needed 2 compilations: one for the
change, and another one to add the "import org.apache.struts.ActionErrors" I
forgot the previous time!

- I decided to adopt Struts style for naming getter/setters arguments and
properties:
class X implements ActionForm {
    String property;
    public void setProperty(final String propety) {
        this.property = property;
    }
...
}
Now, the argument of the method is named with the name of the relevant
property. Scope is discrimined with "this." prefix, so one can refer easily
to the updated property.
But this change can mask subtile errors: in my example, the argument has an
error (missing "r" in "property"), and this error can go undetected at
compile time.
What are the advantages of this naming convention?

- The monolitic tag library is exploded in 4 specialized (form, logic, bean,
template) tag libraries. Appart from the logical and design strutcture, is
there another advantage?
When you reference <struts:link> or <struts-form:link>, the custom tag is
compiled once and the resulting servlet file is saved for future use. In
either case, the resulting class is identical, so there's no performance
benefit (appart from the first compilation time, perhaps). So, in order to
manage future evolutions, is there a possibility to declare <%@taglib
uri="struts-*" prefix="s" %> and have a factorization of the various tag
libraries?

The separation of the libraries make you juggle with the prefixes:
For example, in version 0.5, you had to write:
    <struts:form name="myForm" ...>
        <struts:text property="foo" />
        <struts:property property="bar" />
    </struts:form>
and you obtained the value of the property "bar" of the current form.

With the generalization of version 1.0, you have to explicitely reference
the bean you want the property from, as there's no more reference to the
default form:
    <form:form name="myForm"...>
        <form:text property="foo" />
        <bean:write name="myForm" property="bar" />
    </form:form>




Re: HttpSession.getAttribute() missing?

Posted by Jim Richards <gr...@cyber4.org>.
Then you've got the wrong .jar file in your classpath, or earlier
in your classpath.

You can either edit your CLASSPATH environment variable setting,
or remove the offending .jar file from your system. You'll then
need to include the correct .jar file (depends on your server
setup) that includes the latest classes.

What server are you using?

> The HttpSession it's going after is in the Jswdk version 1.0.1.    Could it mean putValue() instead?

Re: HttpSession.getAttribute() missing?

Posted by "Craig R. McClanahan" <Cr...@eng.sun.com>.
See below.

Mike Campbell wrote:

> > Mike Campbell wrote:
> >
> > > This is an easy question, I'm sure.
> > >
> > > I'm trying to compile my first struts app, and it's blowing up on Action.java not being able to find HttpSession.getAttribute()
> (in
> > > numerous places; first encountered in Action.java, line 300).  I looked at my HttpSession class and sure enough, it isn't there.
> > >
> >
> > The API classes in JSWDK 1.0.1 implement servlet 2.1 and JSP 1.0.  You will need at least servlet 2.2 / JSP 1.1 for Struts to
> work -- I
> > suggest you download Tomcat (3.2 or later) from <http://jakarta.apache.org>.  Among other things, this download includes a
> servlet.jar
> > file with the 2.2/1.1 API classes.
> >
> > Craig McClanahan
>
> Thanks Craig.
>
> in that light, I see also that the tomcat download has:
>  ./lib/ant.jar
> ./lib/jasper.jar
> ./lib/jaxp.jar
> ./lib/parser.jar
> ./lib/servlet.jar
> ./lib/webserver.jar
>
> I'm not using ant, but should I use the jaxp.jar in tomcat in favor of the one the jaxp-1.1ea release by sun?  (And if so, is there
> an equivalent xalan? and crimson.jar?)
>

Tomcat 3.2 is bundled with the libraries from JAXP 1.0 (jaxp.jar and parser.jar).  At that time, no stylesheet processor was included in
JAXP.  You should be able to replace them with the libraries from JAXP 1.1-ea, by removing those two and adding all the JAR files from
the 1.1 release.

>
> Thanks again,
>
> Mike

Craig



Re: HttpSession.getAttribute() missing?

Posted by Mike Campbell <mi...@s1.com>.
> Mike Campbell wrote:
>
> > This is an easy question, I'm sure.
> >
> > I'm trying to compile my first struts app, and it's blowing up on Action.java not being able to find HttpSession.getAttribute()
(in
> > numerous places; first encountered in Action.java, line 300).  I looked at my HttpSession class and sure enough, it isn't there.
> >
>
> The API classes in JSWDK 1.0.1 implement servlet 2.1 and JSP 1.0.  You will need at least servlet 2.2 / JSP 1.1 for Struts to
work -- I
> suggest you download Tomcat (3.2 or later) from <http://jakarta.apache.org>.  Among other things, this download includes a
servlet.jar
> file with the 2.2/1.1 API classes.
>
> Craig McClanahan


Thanks Craig.


in that light, I see also that the tomcat download has:
 ./lib/ant.jar
./lib/jasper.jar
./lib/jaxp.jar
./lib/parser.jar
./lib/servlet.jar
./lib/webserver.jar


I'm not using ant, but should I use the jaxp.jar in tomcat in favor of the one the jaxp-1.1ea release by sun?  (And if so, is there
an equivalent xalan? and crimson.jar?)

Thanks again,

Mike


Re: HttpSession.getAttribute() missing?

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

> This is an easy question, I'm sure.
>
> I'm trying to compile my first struts app, and it's blowing up on Action.java not being able to find HttpSession.getAttribute() (in
> numerous places; first encountered in Action.java, line 300).  I looked at my HttpSession class and sure enough, it isn't there.
>

The API classes in JSWDK 1.0.1 implement servlet 2.1 and JSP 1.0.  You will need at least servlet 2.2 / JSP 1.1 for Struts to work -- I
suggest you download Tomcat (3.2 or later) from <http://jakarta.apache.org>.  Among other things, this download includes a servlet.jar
file with the 2.2/1.1 API classes.

Craig McClanahan



HttpSession.getAttribute() missing?

Posted by Mike Campbell <mi...@s1.com>.
This is an easy question, I'm sure.

I'm trying to compile my first struts app, and it's blowing up on Action.java not being able to find HttpSession.getAttribute() (in
numerous places; first encountered in Action.java, line 300).  I looked at my HttpSession class and sure enough, it isn't there.

The HttpSession it's going after is in the Jswdk version 1.0.1.    Could it mean putValue() instead?

The HttpSession I have has the following API:

getCreationTime()

getId()

 getLastAccessedTime()

 getMaxInactiveInterval()

 getSessionContext()

 getValue(String)

 getValueNames()

 invalidate()

 isNew()

 putValue(String, Object)

 removeValue(String)

 setMaxInactiveInterval(int)



Re: Moving from 0.5 to 1.0: an experience, and design comment

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

> OK, now I see what you are after.  I'm modifying the logic of
processValidate()
> to do the following basic steps:
> * If there is no form bean, skip validation
> * If the request was cancelled, skip validation
> * Call the validate method:
>     * If no errors, continue normal request handling
>       by calling the action etc.
> * (At this point, we know a validate error occurred)
> * If this is a multipart request, roll it back
> * If there is no input form defined, report an error 500
>   because the application is mis-configured (a form bean
>   is defined, but no input page to return to)
>
> Does that sound right?

Excellent. I think you should add an attribute to enable/disable automatic
rollback for multipart forms (when someone upload a few MB file and it
failed because his upload logon is invalid, that's cool to let him a second
chance to enter the logon (in the "input" page) without resubmiting the
file...) and it will be perfect.

Pierre Métras



Re: When Oh When Do We Validate?

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

> Jean-Baptiste Nizet wrote:
>
> >
> > I'm thus in favor of keeping the current behavior, where the form is not
> > validated if the input element is not defined. It's just a matter of form
> > reusability and declarative programming vs classical programming.
> > Now, I wouldn't be too much against the reverse situation, where you would have
> > to specify something in the config file if you want your form NOT to be
> > validated. The best thing to do, IMHO, is to make the presence of a
> > "validateForm" element (true or false) mandatory as soon as a formAttribute is
> > defined. That way, you have the complete declarative control on the validation,
> > and you can't make errors, since the application won't deploy if you forget to
> > specify the element. Of course, you could still set it to false instead of true,
> > but that would be your entire responsibility, and would have the same
> > consequences as inadvertently returning null in your validate method.
> >
> > What do you think?
>
> I'm in favor of being able to configure validation independently of the form also.
> This allows me to use my form object for both setup of the jsp page
> ("preprocessing") and later processing the changes made by the user.  The
> pre-processing requires no validation -- in fact some of my pages broke when
> I downloaded a recent struts which always validates, causing me to revert to my
> previous struts version.
>
> An alternative would be to subclass non-validating  FormX.java to get
> ValidatingFormX.java which just overrides validate(), for all forms FormX which use
> this style.  Personally I'd rather configure this in struts-config.
>

Configurability on a per-mapping basis seems to make the most sense.  I'm going to add
an attribute to the <action> element (and a corresponding property on ActionMapping) to
make this possible.

>
> Jim Newsham

Craig



Re: When Oh When Do We Validate?

Posted by Jim Newsham <ne...@hotu.com>.
Jean-Baptiste Nizet wrote:

>
> I'm thus in favor of keeping the current behavior, where the form is not
> validated if the input element is not defined. It's just a matter of form
> reusability and declarative programming vs classical programming.
> Now, I wouldn't be too much against the reverse situation, where you would have
> to specify something in the config file if you want your form NOT to be
> validated. The best thing to do, IMHO, is to make the presence of a
> "validateForm" element (true or false) mandatory as soon as a formAttribute is
> defined. That way, you have the complete declarative control on the validation,
> and you can't make errors, since the application won't deploy if you forget to
> specify the element. Of course, you could still set it to false instead of true,
> but that would be your entire responsibility, and would have the same
> consequences as inadvertently returning null in your validate method.
>
> What do you think?

I'm in favor of being able to configure validation independently of the form also.
This allows me to use my form object for both setup of the jsp page
("preprocessing") and later processing the changes made by the user.  The
pre-processing requires no validation -- in fact some of my pages broke when
I downloaded a recent struts which always validates, causing me to revert to my
previous struts version.

An alternative would be to subclass non-validating  FormX.java to get
ValidatingFormX.java which just overrides validate(), for all forms FormX which use
this style.  Personally I'd rather configure this in struts-config.

Jim Newsham



Re: When Oh When Do We Validate?

Posted by Jean-Baptiste Nizet <je...@s1.com>.

Pierre Métras wrote:

> Hi Craig,
>
> > Pierre Métras wrote:
> >
> > > As my design seems to be the *bad* one, I think I will have to change my
> > > code (explode my actions in struts-config.xml to create action
> > > /doSomethingInit and /doSomethingValid, and attach an "input" value only
> to
> > > /doSomethingValid, change all my JSP forms with these URL, and in the
> move
> > > suppress the now unused "action" parameter...). And Craig will have to
> > > rollback the CVS :,-(
> >
> > I'm not convinced that it would need to be rolled back -- or at least not
> > completely.
> >
> > Independent of the actions versus sub-actions question on application
> > organization, you also pointed out a real problem -- in the Struts 1.0
> code as
> > it was before this change, consider the following scenario:
> > * You declare your action to require a form bean
> > * Your form bean wants to do validation
> > * You forget to define an "input" parameter
> >   in the action mapping
> > * Struts never calls your validate() method
> > * Your action method gets called, probably
> >   assuming that validation was successful,
> >   and relies on incorrect assumptions.
>
> That's what happened to me. My database was corrupted because I thought that
> the ActionForms information was valid when I forgot to add the "input"
> attribute to the <action>.
>
> >
> > This seems like a Bad Thing for a framework to allow when the developer
> simply
> > forgets to update a configuration file :-(.

I'm not sure this is so bad. Struts is used here as a part of a full J2EE based
application, and J2EE applications are based, in every tier, on configuration
files or deployment descriptors. For instance, you define the transactional
behavior, the database mappings etc. of EJBs in a deployment descriptor. I thus
think that everyone now understands that these deployment descriptors or
configuration files are a critical part of the application, and that as much
care should be taken in defining these files that in the coding of the classes
(if not even more).
I'm thus in favor of keeping the current behavior, where the form is not
validated if the input element is not defined. It's just a matter of form
reusability and declarative programming vs classical programming.
Now, I wouldn't be too much against the reverse situation, where you would have
to specify something in the config file if you want your form NOT to be
validated. The best thing to do, IMHO, is to make the presence of a
"validateForm" element (true or false) mandatory as soon as a formAttribute is
defined. That way, you have the complete declarative control on the validation,
and you can't make errors, since the application won't deploy if you forget to
specify the element. Of course, you could still set it to false instead of true,
but that would be your entire responsibility, and would have the same
consequences as inadvertently returning null in your validate method.

What do you think?

JB.

>
> >
> > As the code sits right this minute, processValdiate() performs the
> following
> > steps, where a "true" return says "go ahead and call the action".
> > (A) If there is no form bean, simply return true
> > (B) If the request was cancelled, simply return true
> >      (higher level logic will skip the call to the action)
> > (C) Call the validate() method.  If it returns no errors,
> >      simply return true
> > ---------- from here on you know an error occurred ----------
> > (D) If this is a multipart request, roll it back
> > (E) Was an input form defined?  If not, throw
> >      an error 500 (internal server error) to document
> >      the mis-configuration problem.
> > (F) Do a RequestDispatcher.forward() to the input form,
> >      and return false.
> >
> > >From what it sounds like, there are particular concerns about step (C) --
> > validate() is always called -- and step (E) -- multipart requests are
> rolled
> > back on validation errors.  I don't really have a problem with either one
> of
> > them, but others might.
> >
> > Can we come to agreement on what the recommended sequence of steps should
> be?
>
> In fact, I would move the question on another view. Should the <action> tag
> be a descriptive or behavioral tag? Do we want to put in it information to
> define the Struts application (which classes are used, where to redirect
> errors, etc.) or must we tend to put into it relations between application
> organization?
> In my opinion, the first situation is encountered presently: we define in
> the tag the different files/classes related to that action. Tha's no more
> than grouping. The problem occurs when we decide to deduce a behavior from
> it: if the "input" attribute is not present, it infers that the programmer
> doesn't want to have validation...
>
> To justify this, I can imagine numerous use cases where one need or not
> validation, or even partial validation (depending on the mapping). My
> present conviction is that the validation is context dependant, and that the
> most flexible place to take the decision to validate or not is in the
> validate method itself, when the programmer can analyse the context (within
> the ActionForm, or analysing the request or mapping).
> So I vote for (C) and call validate all the time.
>
> And as I said in a previous post, if you provide one of a "mustRoolback"
> property in ActionForm (to allow local decisions) or a setRollback method in
> servlet (for global behavior), the programmer can decide in the "validate"
> method what following he wants: rollback upload or not.
> Again, I vote for (D) and let the programmer take the decision.
>
> Maybe, another adhoc solution is to add now an attribute to desactivate vali
> dation, like in the ol' time of ValidatingActionForm...
>     <action     path="/login"
>                     type="com.acme.LoginAction"
>                     input="/login.jsp"
>                     validate="false"       <== doesn't fire validation
>                     ... >
>
> As you said, we can introduce other more "workflow" tags in version 1.1 to
> allows the definition of a validation process from the struts-config.xml
> file...
>
>     <form-bean      name="loginForm"
>                             type="com.acme.LoginForm">
>         <field name="login" mandatory="true" format="alpha*" />
>         <field name="password" format="alphanum*" minSize="4" maxSize="20"
> />
>     </form-bean>
>
> And then let Struts generate the ActionForm file, and why not, the JSP page?
> But that's another story...
>
> Pierre Métras.

--
Jean-Baptiste Nizet
jean-baptiste.nizet@s1.com

R&D Engineer, S1 Belgium
Kleine Kloosterstraat, 23
B-1932 Sint-Stevens Woluwe
+32 2 200 45 42



Re: When Oh When Do We Validate?

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

> Pierre Métras wrote:
>
> > As my design seems to be the *bad* one, I think I will have to change my
> > code (explode my actions in struts-config.xml to create action
> > /doSomethingInit and /doSomethingValid, and attach an "input" value only
to
> > /doSomethingValid, change all my JSP forms with these URL, and in the
move
> > suppress the now unused "action" parameter...). And Craig will have to
> > rollback the CVS :,-(
>
> I'm not convinced that it would need to be rolled back -- or at least not
> completely.
>
> Independent of the actions versus sub-actions question on application
> organization, you also pointed out a real problem -- in the Struts 1.0
code as
> it was before this change, consider the following scenario:
> * You declare your action to require a form bean
> * Your form bean wants to do validation
> * You forget to define an "input" parameter
>   in the action mapping
> * Struts never calls your validate() method
> * Your action method gets called, probably
>   assuming that validation was successful,
>   and relies on incorrect assumptions.

That's what happened to me. My database was corrupted because I thought that
the ActionForms information was valid when I forgot to add the "input"
attribute to the <action>.

>
> This seems like a Bad Thing for a framework to allow when the developer
simply
> forgets to update a configuration file :-(.
>
> As the code sits right this minute, processValdiate() performs the
following
> steps, where a "true" return says "go ahead and call the action".
> (A) If there is no form bean, simply return true
> (B) If the request was cancelled, simply return true
>      (higher level logic will skip the call to the action)
> (C) Call the validate() method.  If it returns no errors,
>      simply return true
> ---------- from here on you know an error occurred ----------
> (D) If this is a multipart request, roll it back
> (E) Was an input form defined?  If not, throw
>      an error 500 (internal server error) to document
>      the mis-configuration problem.
> (F) Do a RequestDispatcher.forward() to the input form,
>      and return false.
>
> >From what it sounds like, there are particular concerns about step (C) --
> validate() is always called -- and step (E) -- multipart requests are
rolled
> back on validation errors.  I don't really have a problem with either one
of
> them, but others might.
>
> Can we come to agreement on what the recommended sequence of steps should
be?

In fact, I would move the question on another view. Should the <action> tag
be a descriptive or behavioral tag? Do we want to put in it information to
define the Struts application (which classes are used, where to redirect
errors, etc.) or must we tend to put into it relations between application
organization?
In my opinion, the first situation is encountered presently: we define in
the tag the different files/classes related to that action. Tha's no more
than grouping. The problem occurs when we decide to deduce a behavior from
it: if the "input" attribute is not present, it infers that the programmer
doesn't want to have validation...

To justify this, I can imagine numerous use cases where one need or not
validation, or even partial validation (depending on the mapping). My
present conviction is that the validation is context dependant, and that the
most flexible place to take the decision to validate or not is in the
validate method itself, when the programmer can analyse the context (within
the ActionForm, or analysing the request or mapping).
So I vote for (C) and call validate all the time.

And as I said in a previous post, if you provide one of a "mustRoolback"
property in ActionForm (to allow local decisions) or a setRollback method in
servlet (for global behavior), the programmer can decide in the "validate"
method what following he wants: rollback upload or not.
Again, I vote for (D) and let the programmer take the decision.


Maybe, another adhoc solution is to add now an attribute to desactivate vali
dation, like in the ol' time of ValidatingActionForm...
    <action     path="/login"
                    type="com.acme.LoginAction"
                    input="/login.jsp"
                    validate="false"       <== doesn't fire validation
                    ... >

As you said, we can introduce other more "workflow" tags in version 1.1 to
allows the definition of a validation process from the struts-config.xml
file...

    <form-bean      name="loginForm"
                            type="com.acme.LoginForm">
        <field name="login" mandatory="true" format="alpha*" />
        <field name="password" format="alphanum*" minSize="4" maxSize="20"
/>
    </form-bean>

And then let Struts generate the ActionForm file, and why not, the JSP page?
But that's another story...


Pierre Métras.


When Oh When Do We Validate? (Was: Re: Moving from 0.5 to 1.0: an experience, and design comment)

Posted by "Craig R. McClanahan" <Cr...@eng.sun.com>.
Pierre Métras wrote:

> As my design seems to be the *bad* one, I think I will have to change my
> code (explode my actions in struts-config.xml to create action
> /doSomethingInit and /doSomethingValid, and attach an "input" value only to
> /doSomethingValid, change all my JSP forms with these URL, and in the move
> suppress the now unused "action" parameter...). And Craig will have to
> rollback the CVS :,-(

I'm not convinced that it would need to be rolled back -- or at least not
completely.

Independent of the actions versus sub-actions question on application
organization, you also pointed out a real problem -- in the Struts 1.0 code as
it was before this change, consider the following scenario:
* You declare your action to require a form bean
* Your form bean wants to do validation
* You forget to define an "input" parameter
  in the action mapping
* Struts never calls your validate() method
* Your action method gets called, probably
  assuming that validation was successful,
  and relies on incorrect assumptions.

This seems like a Bad Thing for a framework to allow when the developer simply
forgets to update a configuration file :-(.

As the code sits right this minute, processValdiate() performs the following
steps, where a "true" return says "go ahead and call the action".
(A) If there is no form bean, simply return true
(B) If the request was cancelled, simply return true
     (higher level logic will skip the call to the action)
(C) Call the validate() method.  If it returns no errors,
     simply return true
---------- from here on you know an error occurred ----------
(D) If this is a multipart request, roll it back
(E) Was an input form defined?  If not, throw
     an error 500 (internal server error) to document
     the mis-configuration problem.
(F) Do a RequestDispatcher.forward() to the input form,
     and return false.

Re: Moving from 0.5 to 1.0: an experience, and design comment

Posted by Pierre Métras <ge...@sympatico.ca>.
Hi Jean-Baptiste,

>
> This doesn't sound right to me at all.
> I've always relied on the presence of the input field to perform
validation or not,
> and I think it's far more easier to switch validation on or off by setting
this
> entry rather than to do it in the code, using the mapping and or request.
This is
> just declarative vs programmative.
>
> Here's a typical usecase I have that, if I'm not missing something, would
have to
> be modified if you made such a change:
> - The user clicks on a link to change his personal information
> - The action is configured with an actionForm, but without input, so that
the
> action can have access to the form, retrieve the info from the database,
populate
> the form, and forward to a JSP page. At this step, the form is empty, or
just
> contains the key of the user we're interested in.
> - The user modifies the information and submits the form. This action is
configured
> to use the same form class, but now has an input parameter, so that the
information
> the user submits is now validated.
>
> This design is used in a lot of cases, and I don't understand how
validating the
> form even if the input parameter is not there would help us, and I don't
see what
> it would add.
>
> Am I missing something?

Now I understand the underlying problem, and I think I have reported some
origins of it in my other messages on design with Struts.

With version 0.5, one can decide easily if he wanted or not validation to
occurs in the ActionForm: you only had to choose between ActionForm or
ValidatingActionForm interfaces.
With version 1.0, the two interfaces where merged in a single class
ActionForm, and there was no simple way to discriminate between validation
or not, apart from assigning a value to the "input" attribute.
So the problem is really, when Struts decides (on what criterium) to call
the validate function of ActionForm? Either programmative or declarative...

With my design to group under one action corelated subactions, perhaps I
have selected the wrong way to use Struts. To reproduce your use case:
- The ActionForm is first called on a URL like "doSomething.do?action=Init".
- Based on the request parameter (or the ActionForm property "action", if
you defined it), I can decide to retrieve info from the database but to to
abort the validation, even if the "input" attribute is defined.
- Then I forward to "edit" that present a JSP page to the user.
- When the user submit the form, I come back on the URL
"doSomething.do?action=Valid". Taking the action request, I can decide to
validate the whole form and redirect to the "input" page if an error occurs.

As my design seems to be the *bad* one, I think I will have to change my
code (explode my actions in struts-config.xml to create action
/doSomethingInit and /doSomethingValid, and attach an "input" value only to
/doSomethingValid, change all my JSP forms with these URL, and in the move
suppress the now unused "action" parameter...). And Craig will have to
rollback the CVS :,-(
Am I alone to have fallen in that trap?

Pierre Métras


Re: Moving from 0.5 to 1.0: an experience, and design comment

Posted by Jean-Baptiste Nizet <je...@s1.com>.

"Craig R. McClanahan" wrote:

> See below.
>
> Pierre Métras wrote:
>
> > [snip]
> > What I proposed is to generate a server error when "input" is not set, and
> > that the servlet can't find the "input" for the action. That's a programming
> > error not to have correctly defined the struts-config.xml file, that's to
> > say have defined a validation method without a corresponding "input" form to
> > display the errors.
> > But when "input" is not defined and the validation doesn't fail, it seems to
> > me that not calling "processValidate" (in fact existing at the beginning of
> > the function) is a source of bugs. The presence of the "input" attribute is
> > now the only mean to tell Struts that your ActionForm is in fact an (old)
> > ValidatingActionForm.
> > I rather prefer to have the call to "ActionForm.validate" occurs every time
> > (and the default "validate" returns "true"), now that ActionForm are
> > ValidatingActionForm, and let the coder decide if he needs validation when
> > he redefines the "validate" method (and he can take a decision at that
> > moment, as now he has access to the mapping and request parameters).
> >
>
> OK, now I see what you are after.  I'm modifying the logic of processValidate()
> to do the following basic steps:
> * If there is no form bean, skip validation
> * If the request was cancelled, skip validation
> * Call the validate method:
>     * If no errors, continue normal request handling
>       by calling the action etc.
> * (At this point, we know a validate error occurred)
> * If this is a multipart request, roll it back
> * If there is no input form defined, report an error 500
>   because the application is mis-configured (a form bean
>   is defined, but no input page to return to)
>
> Does that sound right?

This doesn't sound right to me at all.
I've always relied on the presence of the input field to perform validation or not,
and I think it's far more easier to switch validation on or off by setting this
entry rather than to do it in the code, using the mapping and or request. This is
just declarative vs programmative.

Here's a typical usecase I have that, if I'm not missing something, would have to
be modified if you made such a change:
- The user clicks on a link to change his personal information
- The action is configured with an actionForm, but without input, so that the
action can have access to the form, retrieve the info from the database, populate
the form, and forward to a JSP page. At this step, the form is empty, or just
contains the key of the user we're interested in.
- The user modifies the information and submits the form. This action is configured
to use the same form class, but now has an input parameter, so that the information
the user submits is now validated.

This design is used in a lot of cases, and I don't understand how validating the
form even if the input parameter is not there would help us, and I don't see what
it would add.

Am I missing something?

JB.

>
>
> >
> > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> > Before deverting to a design comment, a documentation bug:
> >
> > The "input" attribute is declared mandatory if the "name" attribute is set,
> > from the DTD.
> >
> >   input           Context-relative path of the input form to which control
> >                      should be returned if a validation error is
> > encountered.
> >                      Required if "name" is specified, else not allowed.
> >
> > This check is not done, and I don't think we need it.
> > ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> >
>
> In effect, isn't this the change implemented as described above?  The new logic
> catches this only if the validate() method returns false, which is really the
> only time we care anyway.  I will clarify that it's not required if your form
> bean does no validation.
>
> (I will comment on the design discussion in a separate message)
>
> Craig

--
Jean-Baptiste Nizet
jean-baptiste.nizet@s1.com

R&D Engineer, S1 Belgium
Kleine Kloosterstraat, 23
B-1932 Sint-Stevens Woluwe
+32 2 200 45 42



Re: Moving from 0.5 to 1.0: an experience, and design comment

Posted by "Craig R. McClanahan" <Cr...@eng.sun.com>.
See below.


Pierre Métras wrote:

> [snip]
> What I proposed is to generate a server error when "input" is not set, and
> that the servlet can't find the "input" for the action. That's a programming
> error not to have correctly defined the struts-config.xml file, that's to
> say have defined a validation method without a corresponding "input" form to
> display the errors.
> But when "input" is not defined and the validation doesn't fail, it seems to
> me that not calling "processValidate" (in fact existing at the beginning of
> the function) is a source of bugs. The presence of the "input" attribute is
> now the only mean to tell Struts that your ActionForm is in fact an (old)
> ValidatingActionForm.
> I rather prefer to have the call to "ActionForm.validate" occurs every time
> (and the default "validate" returns "true"), now that ActionForm are
> ValidatingActionForm, and let the coder decide if he needs validation when
> he redefines the "validate" method (and he can take a decision at that
> moment, as now he has access to the mapping and request parameters).
>

OK, now I see what you are after.  I'm modifying the logic of processValidate()
to do the following basic steps:
* If there is no form bean, skip validation
* If the request was cancelled, skip validation
* Call the validate method:
    * If no errors, continue normal request handling
      by calling the action etc.
* (At this point, we know a validate error occurred)
* If this is a multipart request, roll it back
* If there is no input form defined, report an error 500
  because the application is mis-configured (a form bean
  is defined, but no input page to return to)

Does that sound right?

>
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
> Before deverting to a design comment, a documentation bug:
>
> The "input" attribute is declared mandatory if the "name" attribute is set,
> from the DTD.
>
>   input           Context-relative path of the input form to which control
>                      should be returned if a validation error is
> encountered.
>                      Required if "name" is specified, else not allowed.
>
> This check is not done, and I don't think we need it.
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
>

In effect, isn't this the change implemented as described above?  The new logic
catches this only if the validate() method returns false, which is really the
only time we care anyway.  I will clarify that it's not required if your form
bean does no validation.

(I will comment on the design discussion in a separate message)

Craig



Re: Moving from 0.5 to 1.0: an experience, and design comment

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

> My thinking on multi-page forms is definitely not totally finished yet,
but my
> operating assumption has been that you'd have separate actions for each
page, so
> you could therefore direct errors back to the individual pages.  The
logical
> "grouping" of the actions could happen by subclassing a common base class
that
> represented the shared logic.  You would declare the same form bean for
all of
> these actions, and you'd store this bean in session scope.  (As a side
benefit,
> you can also use "next" and "previous" logical forward names directly,
without
> having to calculate which page you are on in sequence, and then know what
the
> next and previous logical names are.)
>
> It is still messy, because the validation method (at least) needs to know
what
> fields came from what pages, and there is no convenient way to communicate
that
> information so that it only needs to be specified once.  I think that a
final
> solution to this is probably going to need to wait for a 1.1 time frame,
when we
> can figure out how to deal with it cleanly.  I believe that the current
approach
> works quite well for single page forms (with the outstanding issue of
people
> that want to deal with dynamic sets of properties, rather than fixed ones,
which
> will need to be a separate extension if we decide to support it).

Thanks for your explanation.

I've not yet played with multi-page forms, though the <action> example I
included had one. Your design allows to discriminate on the mapping for the
validation call, and make local validation simpler.
My design problem was to consider the ActionForm as the central element and
to offer different views on it with the different forwards of a unique
Action, instead of creating multiple ActionForm. I will wait for version 1.1
to change my code.

Pierre Métras


Re: Old questions that die hard

Posted by Jim Richards <gr...@cyber4.org>.

Ted Husted wrote:
> Jim Richards wrote:
> >The other thing I haven't found reference to yet is
> >client side validation (but I also haven't looked that hard either)
> 
> It's on the 1.1 TODO list.
> 
> And, of course, we're glad that you've checked in again!

I did notice that you had your name down for the client
side validation. I'd be interested in your thoughts, and
ideas because this is something I've done a lot of
recently (not in Struts/JSP though) ...

Please unsubscribe adeniji@computer.org

Posted by Kenny Adeniji <ke...@yahoo.com>.
Please unsubscribe adeniji@computer.org 

--- Ted Husted <ne...@husted.com> wrote:
> My initial thoughts were to look at what some of the
> advanced HTML
> authoring tools, like FrontPage and Dreamweaver do
> with this. Craig
> mentioned to me that the client-side validations
> should be coordinated
> with any new work on server-side validations. 
> 
> Obviously, some standard "domain type" validations
> would be very useful,
> corresponding to Java or SQL types. These might be
> the sorts of things
> we could easily add as properties, and would fit in
> with any IDE
> integration projects.
> 
> These could then be braced server-side with hardcore
> regex validations,
> along with any business logic checking.
> 
> Of course, late-model Javascript also supports regex
> ...
> 
> Jim Richards wrote:
> >>The other thing I haven't found reference to yet
> is
> >>client side validation (but I also haven't looked
> that hard either)
> 
> > I did notice that you had your name down for the
> client
> > side validation. I'd be interested in your
> thoughts, and
> > ideas because this is something I've done a lot of
> > recently (not in Struts/JSP though) ...
> 
> -- Ted Husted, Husted dot Com, Fairport NY USA.
> -- Custom Software ~ Technical Services.
> -- Tel 716 425-0252; Fax 716 223-2506.
> -- http://www.husted.com/about/struts/
> 
> 


__________________________________________________
Do You Yahoo!?
Get personalized email addresses from Yahoo! Mail - only $35 
a year!  http://personal.mail.yahoo.com/

Re: can we remove this user from the list ?

Posted by "Craig R. McClanahan" <Cr...@eng.sun.com>.
Done.

Craig


Maya Muchnik wrote:

> Every time, when I am sending an email I am getting this message (maybe others
> too):
>
> Subject:
>         Mail User is Out of Storage Space
>    Date:
>         .....
>    From:
>         mail@murlmail.com
>
> Can we remove this user ? Maybe he is not there anymore.


can we remove this user from the list ?

Posted by Maya Muchnik <mm...@pumatech.com>.
Every time, when I am sending an email I am getting this message (maybe others
too):

Subject:
        Mail User is Out of Storage Space
   Date:
        .....
   From:
        mail@murlmail.com

Can we remove this user ? Maybe he is not there anymore.



Re: Old questions that die hard

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

> Thank you, David.
> I have tested struts-example with disabled JavaScript on Netscape. It is still
> working!!!
> Maya
>

The only JavaScript code in the Struts example is the attempt to set input focus
on the first field on each form.  In this case, the lack of JavaScript is pretty
innocuous.  For more complex user interfaces, JavaScript might be required (by the
app) to be turned on.

Craig



Re: Old questions that die hard

Posted by Maya Muchnik <mm...@pumatech.com>.
Thank you, David.
I have tested struts-example with disabled JavaScript on Netscape. It is still
working!!!
Maya

"Verratti, David" wrote:

> Hi Maya:
>
> In Netscape 4.7: Choose Edit-->Preferences-->Advanced, unselect enable
> Javascript
>
> Don't think you can in IE, means you can rely on Javascript if you know your
> users are all IE..
>
> see ya
> Dave
>
> -----Original Message-----
> From: mmuchnik [mailto:mmuchnik]On Behalf Of Maya Muchnik
> Sent: 13 February 2001 22:13
> To: struts-user@jakarta.apache.org
> Subject: Re: Old questions that die hard
>
> David,
>
> Could you, please, email, how to disable JavaScript in Netscape and / or IE.
>
> thanks,
>
> Maya
>
> "Verratti, David" wrote:
>
> > Basic rule - don't count on client for anything other than basic html
> unless
> > you can control the client environment.  It's not just ancient browser
> > support, fairly modern browsers (ie Netscape, which I assume would be the
> > default browser for all non-Windows clients) allow users to disable
> > Javascript.
> >
> > see ya
> > Dave
> >
> > -----Original Message-----
> > From: Andrew Collins [mailto:andrewrcollins@yahoo.com]
> > Sent: 13 February 2001 20:18
> > To: struts-user@jakarta.apache.org
> > Subject: Re: Old questions that die hard
> >
> > > Of course, late-model Javascript also supports regex ...
> >
> > Perhaps you mean "newer versions of JavaScript"...
> >
> > (I'm a stickler sometimes, a weissenheimer the remainder.)
> >
> > Is there good cause to support ancient browsers?
> >
> > __________________________________________________
> > Do You Yahoo!?
> > Get personalized email addresses from Yahoo! Mail - only $35
> > a year!  http://personal.mail.yahoo.com/


RE: Old questions that die hard

Posted by "Verratti, David" <dv...@silverstream.com>.
Hi Maya:

In Netscape 4.7: Choose Edit-->Preferences-->Advanced, unselect enable
Javascript

Don't think you can in IE, means you can rely on Javascript if you know your
users are all IE..

see ya
Dave

-----Original Message-----
From: mmuchnik [mailto:mmuchnik]On Behalf Of Maya Muchnik
Sent: 13 February 2001 22:13
To: struts-user@jakarta.apache.org
Subject: Re: Old questions that die hard


David,

Could you, please, email, how to disable JavaScript in Netscape and / or IE.

thanks,

Maya

"Verratti, David" wrote:

> Basic rule - don't count on client for anything other than basic html
unless
> you can control the client environment.  It's not just ancient browser
> support, fairly modern browsers (ie Netscape, which I assume would be the
> default browser for all non-Windows clients) allow users to disable
> Javascript.
>
> see ya
> Dave
>
> -----Original Message-----
> From: Andrew Collins [mailto:andrewrcollins@yahoo.com]
> Sent: 13 February 2001 20:18
> To: struts-user@jakarta.apache.org
> Subject: Re: Old questions that die hard
>
> > Of course, late-model Javascript also supports regex ...
>
> Perhaps you mean "newer versions of JavaScript"...
>
> (I'm a stickler sometimes, a weissenheimer the remainder.)
>
> Is there good cause to support ancient browsers?
>
> __________________________________________________
> Do You Yahoo!?
> Get personalized email addresses from Yahoo! Mail - only $35
> a year!  http://personal.mail.yahoo.com/

Re: Old questions that die hard

Posted by Maya Muchnik <mm...@pumatech.com>.
David,

Could you, please, email, how to disable JavaScript in Netscape and / or IE.

thanks,

Maya

"Verratti, David" wrote:

> Basic rule - don't count on client for anything other than basic html unless
> you can control the client environment.  It's not just ancient browser
> support, fairly modern browsers (ie Netscape, which I assume would be the
> default browser for all non-Windows clients) allow users to disable
> Javascript.
>
> see ya
> Dave
>
> -----Original Message-----
> From: Andrew Collins [mailto:andrewrcollins@yahoo.com]
> Sent: 13 February 2001 20:18
> To: struts-user@jakarta.apache.org
> Subject: Re: Old questions that die hard
>
> > Of course, late-model Javascript also supports regex ...
>
> Perhaps you mean "newer versions of JavaScript"...
>
> (I'm a stickler sometimes, a weissenheimer the remainder.)
>
> Is there good cause to support ancient browsers?
>
> __________________________________________________
> Do You Yahoo!?
> Get personalized email addresses from Yahoo! Mail - only $35
> a year!  http://personal.mail.yahoo.com/


RE: Old questions that die hard

Posted by "Verratti, David" <dv...@silverstream.com>.
Basic rule - don't count on client for anything other than basic html unless
you can control the client environment.  It's not just ancient browser
support, fairly modern browsers (ie Netscape, which I assume would be the
default browser for all non-Windows clients) allow users to disable
Javascript.

see ya
Dave


-----Original Message-----
From: Andrew Collins [mailto:andrewrcollins@yahoo.com]
Sent: 13 February 2001 20:18
To: struts-user@jakarta.apache.org
Subject: Re: Old questions that die hard


> Of course, late-model Javascript also supports regex ...

Perhaps you mean "newer versions of JavaScript"...

(I'm a stickler sometimes, a weissenheimer the remainder.)

Is there good cause to support ancient browsers?

__________________________________________________
Do You Yahoo!?
Get personalized email addresses from Yahoo! Mail - only $35
a year!  http://personal.mail.yahoo.com/

Re: Old questions that die hard

Posted by Andrew Collins <an...@yahoo.com>.
> Of course, late-model Javascript also supports regex ...

Perhaps you mean "newer versions of JavaScript"...

(I'm a stickler sometimes, a weissenheimer the remainder.)

Is there good cause to support ancient browsers?

__________________________________________________
Do You Yahoo!?
Get personalized email addresses from Yahoo! Mail - only $35 
a year!  http://personal.mail.yahoo.com/

RE: Client-side validation (Old questions that die hard)

Posted by Neal Kaiser <ne...@makeastore.com>.
Dave,

One functionality that might be nice for the validation you are working on:

The ability to say that a field is required IF a certain form parameter
exists.

Something like:

<logic:equal name="registrationForm" property="role"
                  scope="request" value="Admin">

 <field    property="addr"
      		displayname="registrationForm.addr.displayname"
      		required="true"/>

</logic:equal>

So, the property "addr" is validated ONLY if the
registrationForm.role="Admin"

That's probably not the best syntax, but I think you get what I mean.

Thanks, Neal


> -----Original Message-----
> From: David Winterfeldt [mailto:dwinterfeldt@yahoo.com]
> Sent: Thursday, February 15, 2001 12:06 PM
> To: struts-user@jakarta.apache.org
> Subject: Re: Client-side validation (Old questions that die hard)
>
>
> I actually had some built-in expressions for testing,
> but then I pulled it out for simplicity.  I had some
> basic things like phone numbers and such hard coded in
> and checking for a date (leap year, etc.), but I
> thought it might be better to wait and think about it
> a little more so someone could plug in their own date
> validation function if they wanted to.
>
> Although I assume you're talking about primitives,
> String, and Date which would cover a lot forms.  I
> hadn't really thought about that, but it is a good
> idea.  I could add a type attribute to the field
> element (ex: type="int").  I was hoping that before I
> did too much more on it that if it looked like a good
> start it could be used and/or modified for the struts
> validation in 1.1.  I would be interested in being
> involved in working on the validation framework.  So I
> thought it would be a good idea to hear about ideas
> and what the validation framework should do before I
> did more work.  As the validation starts expanding, it
> may be a lot of work to keep the client side
> javascript in sync with it.  Although if everything is
> kept clean enough that you call a method to do
> something there could be an equivalent Javascript
> method (as long as it doesn't hit a database or server
> side resource).
>
> It would also be nice to have basic expressions like
> this value should be an int and when that is confirmed
> be able to check if it is in a range.
>
> Ted, do you have an opinion on how locale should be
> handled if validation rules are kept in an xml file?
> Should there be a separate file for each locale like
> resource files or an attribute in the xml file.  I
> could make a 'form set' element and it could have a
> locale attribute.  You could then group forms in a
> locale and even set one group as a default.  I was
> also thinking about making validation resource class
> like MessageResource and putting that in application
> scope instead of a Hashtable.  To keep the validation
> in line with struts, it would be important to be able
> to specify different validation rules for different
> countries.
>
>
> David
>
> --- Ted Husted <ne...@husted.com> wrote:
> > David Winterfeldt wrote:
> > > I posted the code and a example war at.  Ted, if
> > you
> > > want to, you can add this to the list of struts
> > > sites/resources you have.
> >
> > I've added this to my list at <
> > http://husted.com/about/struts >, along
> > with Craig T's very kewl presentation.
> >
> > If this keeps up, we're going to need an
> > announcement list just to keep
> > up with the new Struts resources!
> >
> > I'm hip deep (down from neck deep) in the
> > Dreamweaver UltraDev tutorials
> > right now, but as soon that's done, I'm back to
> > refining validation
> > for my working application -- which would now mean
> > taking your Validator
> > for a spin!
> >
> > What I really like about this at first glance is the
> > XML configuration.
> > This plays well into integrating this both with
> > Struts and with visual
> > environments, like UltraDev.
> >
> > Have you thought about offering built-in expressions
> > for standard Java
> > and SQL types?
> >
> > -- Ted Husted, Husted dot Com, Fairport NY USA.
> > -- Custom Software ~ Technical Services.
> > -- Tel 716 425-0252; Fax 716 223-2506.
> > -- http://www.husted.com/about/struts/
>
>
> __________________________________________________
> Do You Yahoo!?
> Get personalized email addresses from Yahoo! Mail - only $35
> a year!  http://personal.mail.yahoo.com/
>


Re: Client-side validation (Old questions that die hard)

Posted by David Winterfeldt <dw...@yahoo.com>.
I actually had some built-in expressions for testing,
but then I pulled it out for simplicity.  I had some
basic things like phone numbers and such hard coded in
and checking for a date (leap year, etc.), but I
thought it might be better to wait and think about it
a little more so someone could plug in their own date
validation function if they wanted to.  

Although I assume you're talking about primitives,
String, and Date which would cover a lot forms.  I
hadn't really thought about that, but it is a good
idea.  I could add a type attribute to the field
element (ex: type="int").  I was hoping that before I
did too much more on it that if it looked like a good
start it could be used and/or modified for the struts
validation in 1.1.  I would be interested in being
involved in working on the validation framework.  So I
thought it would be a good idea to hear about ideas
and what the validation framework should do before I
did more work.  As the validation starts expanding, it
may be a lot of work to keep the client side
javascript in sync with it.  Although if everything is
kept clean enough that you call a method to do
something there could be an equivalent Javascript
method (as long as it doesn't hit a database or server
side resource).  

It would also be nice to have basic expressions like
this value should be an int and when that is confirmed
be able to check if it is in a range.

Ted, do you have an opinion on how locale should be
handled if validation rules are kept in an xml file? 
Should there be a separate file for each locale like
resource files or an attribute in the xml file.  I
could make a 'form set' element and it could have a
locale attribute.  You could then group forms in a
locale and even set one group as a default.  I was
also thinking about making validation resource class
like MessageResource and putting that in application
scope instead of a Hashtable.  To keep the validation
in line with struts, it would be important to be able
to specify different validation rules for different
countries.


David

--- Ted Husted <ne...@husted.com> wrote:
> David Winterfeldt wrote:
> > I posted the code and a example war at.  Ted, if
> you
> > want to, you can add this to the list of struts
> > sites/resources you have.  
> 
> I've added this to my list at <
> http://husted.com/about/struts >, along
> with Craig T's very kewl presentation.
> 
> If this keeps up, we're going to need an
> announcement list just to keep
> up with the new Struts resources!
> 
> I'm hip deep (down from neck deep) in the
> Dreamweaver UltraDev tutorials
> right now, but as soon that's done, I'm back to
> refining validation
> for my working application -- which would now mean
> taking your Validator
> for a spin!
> 
> What I really like about this at first glance is the
> XML configuration.
> This plays well into integrating this both with
> Struts and with visual
> environments, like UltraDev. 
> 
> Have you thought about offering built-in expressions
> for standard Java 
> and SQL types?
> 
> -- Ted Husted, Husted dot Com, Fairport NY USA.
> -- Custom Software ~ Technical Services.
> -- Tel 716 425-0252; Fax 716 223-2506.
> -- http://www.husted.com/about/struts/


__________________________________________________
Do You Yahoo!?
Get personalized email addresses from Yahoo! Mail - only $35 
a year!  http://personal.mail.yahoo.com/

Re: Client-side validation (Old questions that die hard)

Posted by Ted Husted <ne...@husted.com>.
David Winterfeldt wrote:
> I posted the code and a example war at.  Ted, if you
> want to, you can add this to the list of struts
> sites/resources you have.  

I've added this to my list at < http://husted.com/about/struts >, along
with Craig T's very kewl presentation.

If this keeps up, we're going to need an announcement list just to keep
up with the new Struts resources!

I'm hip deep (down from neck deep) in the Dreamweaver UltraDev tutorials
right now, but as soon that's done, I'm back to refining validation
for my working application -- which would now mean taking your Validator
for a spin!

What I really like about this at first glance is the XML configuration.
This plays well into integrating this both with Struts and with visual
environments, like UltraDev. 

Have you thought about offering built-in expressions for standard Java 
and SQL types?

-- Ted Husted, Husted dot Com, Fairport NY USA.
-- Custom Software ~ Technical Services.
-- Tel 716 425-0252; Fax 716 223-2506.
-- http://www.husted.com/about/struts/

Re: Old questions that die hard

Posted by David Winterfeldt <dw...@yahoo.com>.
I added basic client side javascript validation that
matches the server side validation.  Validation rules
are stored in an xml file.  

I thought that if the form had a locale attribute that
would take care of i18n or there could be separate
files like the property resource files.

I was also thinking about how open the validation
framework should be.  If it could be configured a
little like some Ant tasks, you could define a method
to perform validation and what validation need to
finish before others proceed like the Ant depends
attribute.
   <name="required"
    class="org.apache.struts.Validation"
    property="validateRequired"/>

   <name="regexp"
    class="org.apache.struts.Validation"
    property="validateRegexp"
    depends="required"/>

   <field property="firstName" 
          validations="required,regexp" 
          mask="^\w+$" /> 

I thought of this because I'm checking for all
required fields before continuing to check the regular
expressions.  Anyway, it's late.  I hope that part
made sense.

I posted the code and a example war at.  Ted, if you
want to, you can add this to the list of struts
sites/resources you have.  Is this something along the
lines you were thinking of?  Let me know what you
think of Ted.
http://home.earthlink.net/~dwinterfeldt

David Winterfeldt

--- Ted Husted <ne...@husted.com> wrote:
> My initial thoughts were to look at what some of the
> advanced HTML
> authoring tools, like FrontPage and Dreamweaver do
> with this. Craig
> mentioned to me that the client-side validations
> should be coordinated
> with any new work on server-side validations. 
> 
> Obviously, some standard "domain type" validations
> would be very useful,
> corresponding to Java or SQL types. These might be
> the sorts of things
> we could easily add as properties, and would fit in
> with any IDE
> integration projects.
> 
> These could then be braced server-side with hardcore
> regex validations,
> along with any business logic checking.
> 
> Of course, late-model Javascript also supports regex
> ...
> 
> Jim Richards wrote:
> >>The other thing I haven't found reference to yet
> is
> >>client side validation (but I also haven't looked
> that hard either)
> 
> > I did notice that you had your name down for the
> client
> > side validation. I'd be interested in your
> thoughts, and
> > ideas because this is something I've done a lot of
> > recently (not in Struts/JSP though) ...
> 
> -- Ted Husted, Husted dot Com, Fairport NY USA.
> -- Custom Software ~ Technical Services.
> -- Tel 716 425-0252; Fax 716 223-2506.
> -- http://www.husted.com/about/struts/


__________________________________________________
Do You Yahoo!?
Get personalized email addresses from Yahoo! Mail - only $35 
a year!  http://personal.mail.yahoo.com/

Re: Proper way to 'forward' dynamically

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

> I haven't been able to find a question regarding this particular
> circumstance, so hopefully this isn't in an FAQ somewhere!
>
> In my Action subclass, rather than returning the results of
> mapping.findForward(...) I need to forward to a page determined at runtime.
> What is the *proper* way to forward to xxx.jsp?  Should I construct an
> ActionForward?  (tried that unsuccessfully).
>

When I need this, I just create a new ActionForward dynamically:

    String path = ... create context-relative path to new page ...
    return (new ActionForward(path));

The path you calculate must be context relative and start with a slash, exactly
like the "path" attributes to your standard <forward> elements.

>
> Thanks for any help,
>
> Dennis

Craig



Proper way to 'forward' dynamically

Posted by Dennis <de...@iswsolutions.com>.
I haven't been able to find a question regarding this particular
circumstance, so hopefully this isn't in an FAQ somewhere!

In my Action subclass, rather than returning the results of
mapping.findForward(...) I need to forward to a page determined at runtime.
What is the *proper* way to forward to xxx.jsp?  Should I construct an
ActionForward?  (tried that unsuccessfully).


Thanks for any help,

Dennis


Re: Old questions that die hard

Posted by Ted Husted <ne...@husted.com>.
My initial thoughts were to look at what some of the advanced HTML
authoring tools, like FrontPage and Dreamweaver do with this. Craig
mentioned to me that the client-side validations should be coordinated
with any new work on server-side validations. 

Obviously, some standard "domain type" validations would be very useful,
corresponding to Java or SQL types. These might be the sorts of things
we could easily add as properties, and would fit in with any IDE
integration projects.

These could then be braced server-side with hardcore regex validations,
along with any business logic checking.

Of course, late-model Javascript also supports regex ...

Jim Richards wrote:
>>The other thing I haven't found reference to yet is
>>client side validation (but I also haven't looked that hard either)

> I did notice that you had your name down for the client
> side validation. I'd be interested in your thoughts, and
> ideas because this is something I've done a lot of
> recently (not in Struts/JSP though) ...

-- Ted Husted, Husted dot Com, Fairport NY USA.
-- Custom Software ~ Technical Services.
-- Tel 716 425-0252; Fax 716 223-2506.
-- http://www.husted.com/about/struts/

Re: Old questions that die hard

Posted by Jim Richards <gr...@cyber4.org>.

Ted Husted wrote:
> Jim Richards wrote:
> >The other thing I haven't found reference to yet is
> >client side validation (but I also haven't looked that hard either)
> 
> It's on the 1.1 TODO list.
> 
> And, of course, we're glad that you've checked in again!

I did notice that you had your name down for the client
side validation. I'd be interested in your thoughts, and
ideas because this is something I've done a lot of
recently (not in Struts/JSP though) ...

Re: Old questions that die hard

Posted by Ted Husted <ne...@husted.com>.
Jim Richards wrote:
>The other thing I haven't found reference to yet is
>client side validation (but I also haven't looked that hard either)

It's on the 1.1 TODO list. 

And, of course, we're glad that you've checked in again!

Old questions that die hard

Posted by Jim Richards <gr...@cyber4.org>.
I've been out of the Struts loop for a few weeks (or months, or years based on
Internet time) and I am impressed that almost everything is ready for a 1.0
release, which means Craig's comments below still stand, re: Multipage forms
and forms built dynamically. The other thing I haven't found reference to yet is
client side validation (but I also haven't looked that hard either)

I'll have to start digging deep again.

Craig wrote:
>My thinking on multi-page forms is definitely not totally finished yet, but my
>operating assumption has been that you'd have separate actions for each page, so
>you could therefore direct errors back to the individual pages.  The logical
>"grouping" of the actions could happen by subclassing a common base class that
>represented the shared logic.  You would declare the same form bean for all of
>these actions, and you'd store this bean in session scope.  (As a side benefit,
>you can also use "next" and "previous" logical forward names directly, without
>having to calculate which page you are on in sequence, and then know what the
>next and previous logical names are.)
>
>It is still messy, because the validation method (at least) needs to know what
>fields came from what pages, and there is no convenient way to communicate that
>information so that it only needs to be specified once.  I think that a final
>solution to this is probably going to need to wait for a 1.1 time frame, when we
>can figure out how to deal with it cleanly.  I believe that the current approach
>works quite well for single page forms (with the outstanding issue of people
>that want to deal with dynamic sets of properties, rather than fixed ones, which
>will need to be a separate extension if we decide to support it).


--
Mary had a crypto key
 she kept it in escrow
  and everything that Mary said
    the Feds were sure to know.

Re: Moving from 0.5 to 1.0: an experience, and design comment

Posted by "Craig R. McClanahan" <Cr...@eng.sun.com>.
Pierre Métras wrote:

> [snip]
> Now, a long comment on design with Struts...
>
> In fact, my opinion is not definitely set, when studying the Struts example,
> and perhaps due to a design deviation...:
>
>     <!-- Edit mail subscription -->
>     <action    path="/editSubscription"
>                type="org.apache.struts.example.EditSubscriptionAction"
>                name="subscriptionForm"
>               scope="request">
>       <forward name="failure"          path="/mainMenu.jsp"/>
>       <forward name="success"       path="/subscription.jsp"/>
>     </action>
>
>     <!-- Save mail subscription -->
>     <action    path="/saveSubscription"
>                type="org.apache.struts.example.SaveSubscriptionAction"
>                name="subscriptionForm"
>               scope="request"
>               input="/subscription.jsp">
>       <forward name="success"
> path="/editRegistration.do?action=Edit"/>
>     </action>
>
> >From that extract, the check for validation will only occur on the
> "saveSubscription" action only. A user can change his subscription
> information, but defer the validation to the moment when that info is saved
> to database.
> This behavior can be interesting for multipages forms, but should we define
> it in the configuration file or in the "validate" method?
>
> The example uses a "N Action - 1 ActionForm" design that allows to define an
> "input" attribute for each Action error processing, where I used a "1
> Action - 1 ActionForm" one in my application:
>
> <action path="/subscription"
>         ...
>         name="subscriptionForm">
>     <forward name="init"              path="/page1.jsp">
>     <forward name="editPage1"   path="/page1.jsp">
>     <forward name="editPage2"   path="/page2.jsp">
>     <forward name="save"           path="/display.jsp">
>     <forward name="display"       path="/display.jsp">
>     <forward name="exit"            path="/menu.do">
> </action>
>
> I've used and <action> definition as a way to group related JSP pages, for
> instance, editing and displaying a user subscription. Selecting between the
> different sub-actions is done using a URL like
> "/subscription.do?action=init". All treatments concerning the subscription
> process are centralized in the "SubscriptionAction" class.
>
> A problem with such a design is that when an error occurs, you can't
> redirect to a default error page (it depends on the subaction you were
> performing)... In that case, I would think that the "validate" function
> should decide which error forward should be used:
>
> validate()
>     - local validation on page 1 data
>         if error, forward to errorPage1
>     - local validation on page 2 data
>         if error, forward to errorPage2
>     - global validation
>         if error, forward to inputPage
>
> Comments? Have others "missed" the original Struts design?
> Now is not the time to change version 1.0 API, just before release (and now
> that my application runs without it). But is it a desired extension for 1.1?
>

My thinking on multi-page forms is definitely not totally finished yet, but my
operating assumption has been that you'd have separate actions for each page, so
you could therefore direct errors back to the individual pages.  The logical
"grouping" of the actions could happen by subclassing a common base class that
represented the shared logic.  You would declare the same form bean for all of
these actions, and you'd store this bean in session scope.  (As a side benefit,
you can also use "next" and "previous" logical forward names directly, without
having to calculate which page you are on in sequence, and then know what the
next and previous logical names are.)

It is still messy, because the validation method (at least) needs to know what
fields came from what pages, and there is no convenient way to communicate that
information so that it only needs to be specified once.  I think that a final
solution to this is probably going to need to wait for a 1.1 time frame, when we
can figure out how to deal with it cleanly.  I believe that the current approach
works quite well for single page forms (with the outstanding issue of people
that want to deal with dynamic sets of properties, rather than fixed ones, which
will need to be a separate extension if we decide to support it).

Thanks for all of your deep thinking on this, and thanks for sharing the
conversion experiences!

>
> Pierre Métras

Craig



Re: Moving from 0.5 to 1.0: an experience, and design comment

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

> >
> > > mapping.getInput() works OK if you have the "input" attribute set in
> > > the corresponding action tag in struts-config.xml
> >
> > Yes. I found that one later. I didn't investigate why it worked in
version
> > 0.5, perhaps due to new bugs that I introduced bugs when I rewrote my
> > struts-config.xml file.
> >
> > Also, I suggested yesterday a change in the
ActionServlet.performValidate
> > method to the struts-dev list, for calling the ActionForm.validate even
when
> > the "input" attribute is not set.
> >
>
> What would the controller servlet do if the validate() method returned
errors in
> this case?  It doesn't know where to send the user back to (that's what
the
> input attribute is there to tell it), and there is no other current
mechanism to
> let the action that is called know that there were validation problems.


Yes, the "input" attribute is necessary when the validation fails, but not
when it succeeds!

What I proposed is to generate a server error when "input" is not set, and
that the servlet can't find the "input" for the action. That's a programming
error not to have correctly defined the struts-config.xml file, that's to
say have defined a validation method without a corresponding "input" form to
display the errors.
But when "input" is not defined and the validation doesn't fail, it seems to
me that not calling "processValidate" (in fact existing at the beginning of
the function) is a source of bugs. The presence of the "input" attribute is
now the only mean to tell Struts that your ActionForm is in fact an (old)
ValidatingActionForm.
I rather prefer to have the call to "ActionForm.validate" occurs every time
(and the default "validate" returns "true"), now that ActionForm are
ValidatingActionForm, and let the coder decide if he needs validation when
he redefines the "validate" method (and he can take a decision at that
moment, as now he has access to the mapping and request parameters).


~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Before deverting to a design comment, a documentation bug:

The "input" attribute is declared mandatory if the "name" attribute is set,
from the DTD.

  input           Context-relative path of the input form to which control
                     should be returned if a validation error is
encountered.
                     Required if "name" is specified, else not allowed.


This check is not done, and I don't think we need it.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~


Now, a long comment on design with Struts...

In fact, my opinion is not definitely set, when studying the Struts example,
and perhaps due to a design deviation...:

    <!-- Edit mail subscription -->
    <action    path="/editSubscription"
               type="org.apache.struts.example.EditSubscriptionAction"
               name="subscriptionForm"
              scope="request">
      <forward name="failure"          path="/mainMenu.jsp"/>
      <forward name="success"       path="/subscription.jsp"/>
    </action>

    <!-- Save mail subscription -->
    <action    path="/saveSubscription"
               type="org.apache.struts.example.SaveSubscriptionAction"
               name="subscriptionForm"
              scope="request"
              input="/subscription.jsp">
      <forward name="success"
path="/editRegistration.do?action=Edit"/>
    </action>

Re: Moving from 0.5 to 1.0: an experience

Posted by "Craig R. McClanahan" <Cr...@eng.sun.com>.

Pierre Métras wrote:

> Hi Luke,
>
> > mapping.getInput() works OK if you have the "input" attribute set in
> > the corresponding action tag in struts-config.xml
>
> Yes. I found that one later. I didn't investigate why it worked in version
> 0.5, perhaps due to new bugs that I introduced bugs when I rewrote my
> struts-config.xml file.
>
> Also, I suggested yesterday a change in the ActionServlet.performValidate
> method to the struts-dev list, for calling the ActionForm.validate even when
> the "input" attribute is not set.
>

What would the controller servlet do if the validate() method returned errors in
this case?  It doesn't know where to send the user back to (that's what the
input attribute is there to tell it), and there is no other current mechanism to
let the action that is called know that there were validation problems.

>
> Pierre Métras

Craig

Re: Moving from 0.5 to 1.0: an experience

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

> mapping.getInput() works OK if you have the "input" attribute set in
> the corresponding action tag in struts-config.xml

Yes. I found that one later. I didn't investigate why it worked in version
0.5, perhaps due to new bugs that I introduced bugs when I rewrote my
struts-config.xml file.

Also, I suggested yesterday a change in the ActionServlet.performValidate
method to the struts-dev list, for calling the ActionForm.validate even when
the "input" attribute is not set.

Pierre Métras


Re: Moving from 0.5 to 1.0: an experience

Posted by Luke Taylor <ne...@freesurf.ch>.

Pierre Métras wrote:
> 
> 
> Second (well, times later) run
> ====================
> - java.lang.NullPointerException
> at
> org.apache.struts.action.ActionServlet.processActionPerform(ActionServlet.ja
> va:1375)
> at org.apache.struts.action.ActionServlet.process(ActionServlet.java:1241)
> at org.apache.struts.action.ActionServlet.doGet(ActionServlet.java:417)
> at javax.servlet.http.HttpServlet.service(HttpServlet.java:740)
> etc...
> 
> I used to write:
>             return new ActionForward(mapping.getInput());
> in "Action.process" when I wanted my action to return to the calling form
> (partial validation, error...).
> Now, the getInput call returns null, instead of the original path, so the
> RequestDispatcher in ActionServlet fails to forward the request, and thus
> the NullPointerException.
> I didn't investigate enough to find if this is now a "normal" feature of
> version 1.0. There was a similar bug discussed in the mailing list the 15th
> Aug 2000, but it was diagnosed to an action.xml error. I doubled check my
> struts-config.xml and it seems correct.
> 

mapping.getInput() works OK if you have the "input" attribute set in
the corresponding action tag in struts-config.xml

Luke.



> Change it to:
>             return mapping.findForward("forwardName")
> But don't forget to add the new "forwardName" in struts-config.xml
> 


-- 
 Luke Taylor.
 PGP Key ID: 0x57E9523C