Tomcat 5/Struts 1.1: Simple login form shows errors when accessed 1st time

B

Brian O. Bush

All.
I have a login jsp page, and when i first access the login jsp page
(below), the validation errors are displayed as if someone had already
submitted the form. I thought that the bean was only validated upon
submit? Is there something else going on with the loginForm bean that
i have defined in the struts-config.xml. Another page I have does the
same thing..., and everything works fine, except for the fact that the
user sees error messages prior to doing anything. BTW, I have already
shift-reloaded the form to make sure it wasn't a caching issue.

Any help would be great!

Thanks, Brian

----------------------------------------------------------------
login.jsp:

....
<html:form action="/login" focus="username">
....
<html:text property="username" size="24" maxlength="18"/>
<html:errors property="username"/></td>
....
<html:password property="password" size="24" maxlength="18"
redisplay="false"/>
<html:errors property="password"/></td>
....
<html:submit><bean:message key="button.submit"/></html:submit>
</html:form>



----------------------------------------------------------------
validation.xml:

<form-validation>
<formset>

<form name="loginForm">
<field property="username"
depends="required, minlength, maxlength,
email">
<arg0 key="forms.login.username"/>
<arg1 key="${var:minlength}" name="minlength"
resource="false"/>
<arg2 key="${var:maxlength}" name="maxlength"
resource="false"/>
<var>
<var-name>maxlength</var-name>
<var-value>16</var-value>
</var>
<var>
<var-name>minlength</var-name>
<var-value>3</var-value>
</var>
</field>

....
</form>
</formset>
</form-validation>

----------------------------------------------------------------
struts-config.xml:
<form-beans>
<form-bean name="loginForm"
type="org.apache.struts.validator.DynaValidatorForm">
<form-property name="username" type="java.lang.String"/>
<form-property name="password" type="java.lang.String"/>
</form-bean>
</form-beans>
....
<action path="/login"
type="com.blah.actions.LoginAction"
input="main.loginForm"
scope="session"
name="loginForm">
<forward name="next" path="index" />
</action>
----------------------------------------------------------------
com.blah.actions.LoginAction:


execute(...){
....
if (valid) {
HttpSession session = request.getSession();
if (session != null) {
session.setAttribute(Constants.USER_KEY, user);
}
} else {
errors.add(ActionErrors.GLOBAL_ERROR,
new ActionError("action.error.login"));
return(mapping.getInputForward());
}
....
return(mapping.findForward(Constants.NEXT));
 
B

Brian O. Bush

In validation errors, I mean the resources printed out from code in
the login.jsp, e.g.,

<html:errors property="username"/>
and
<html:errors property="password"/>

Where the user would see the following:

Login
Username: --------
Username is required.
Password: --------
Password is required.


Thanks,
Brian
 
S

Sudsy

Brian said:
All.
I have a login jsp page, and when i first access the login jsp page
(below), the validation errors are displayed as if someone had already
submitted the form. I thought that the bean was only validated upon
submit? Is there something else going on with the loginForm bean that
i have defined in the struts-config.xml. Another page I have does the
same thing..., and everything works fine, except for the fact that the
user sees error messages prior to doing anything. BTW, I have already
shift-reloaded the form to make sure it wasn't a caching issue.

Any help would be great!

Thanks, Brian

Have users go directly to login.jsp rather than the login Action.
For more on processing flow, check out this article:
<http://www.sudsy.net/technology/struts-arch.html>
It shows that as soon as you enter the action, the corresponding
ActionForm is reset() then populated with the request parameters.
If validate="true" is specified then validate() is invoked on the
ActionForm.
 
W

Wendy S

Sudsy said:
Have users go directly to login.jsp rather than the login Action.

Sudsy, I'm shocked! IMO, users should *always* go through the Action. In
fact, my JSP's live under WEB-INF-- you can't get to them directly. All you
need is a bit of logic to determine whether this is the "first time" and if
so, skip validation.

In the ActionForm (or whatever descendant you're using, I use
DynaValidatorForm):

public ActionErrors validate( ActionMapping mapping,
HttpServletRequest request )
{
ActionErrors errors = new ActionErrors();

// decide whether this is the "first time"

if ( !firstTime ) {
log.debug( "validating..." );
errors = super.validate( mapping, request );
}

return errors;
}

The decision can be any number of things. Was the form POSTed to you, or
was it a GET? Does a hidden field on the form have a value?
 
S

Sudsy

Wendy said:
Sudsy, I'm shocked! IMO, users should *always* go through the Action. In
fact, my JSP's live under WEB-INF-- you can't get to them directly. All you
need is a bit of logic to determine whether this is the "first time" and if
so, skip validation.

Perhaps you'd like to compose a reply describing those approaches
in detail? (The GET/POST differentiation isn't applicable in a
number of scenarios, BTW.) My posted solution works and is easily
implemented.
 
B

Brian O. Bush

Ok, thanks for the reply... however, now I am totally confused. None
of the books or examples I have on this mention this problem. Or is
this just expected behavior...?

Also (1) I am using tiles (hence I don't really have a login.jsp, just
a combination of login_content.jsp, header.jsp, etc)
(2) I don't have a LoginForm (I once did, but retired it when I moved
to DynaValidatorForms...) so I don't have a validate method to check
for the first time it was accessed.

The workarounds mentioned are nice, but somehow it feels like this is
a problem (it happens on all my forms) and is not proper behavior. Has
the struts developers intentionally designed it so that the form upon
creation has the validate method called?

Brian
 
T

Tim

Since I'm just learning Struts myself, I've been avoiding getting in on
this conversation, however, since it's been going on for a while....
I have an example that I've found where the validation only occurs when
the submit button has been clicked.
Therefore, I would think this is the correct result.
 
W

Wendy S

Brian O. Bush said:
(2) I don't have a LoginForm (I once did, but retired it when I moved
to DynaValidatorForms...) so I don't have a validate method to check
for the first time it was accessed.

Using DynaValidatorForm only gets you out of writing a bunch of get/set
methods. You can still have a Java class that extends DynaValidatorForm and
override the validate method. It looks like this:

public final class ContactForm extends DynaValidatorForm
{ ...

and in struts-config, you use your form as the type rather than the generic
DynaValidatorForm:
<form-beans>
<form-bean name="contactForm"
type="edu.asu.vpia.struts.ContactForm">
...

Struts then knows to instantiate your class rather than DynaValidatorForm.
The workarounds mentioned are nice, but somehow it feels like this is
a problem (it happens on all my forms) and is not proper behavior. Has
the struts developers intentionally designed it so that the form upon
creation has the validate method called?

HTTP request -> form creation -> form population from request params -> form
validation -> display
The framework doesn't particularly care that the form is "new," it just
goes through the steps. Another option is to turn off validation in
struts-config.xml, and call it manually when you determine it's appropriate.

Hard-coded, my check of whether to validate looks like this:

if ( "Finish".equals( request.getParameter( "userAction" ) ) ) {
log.debug( "User has Finished, validating..." );
errors = super.validate( mapping, request );
}

'userAction' is the param that controls my LookupDispatchAction, and
"Finish" is the value of one of the many buttons on the form. One of these
days I'll get the former value from the ActionMapping and the latter from
the Resource bundle. This app suffers from being my very first Struts app,
and I find the oddest things when I go back and look at the code!
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,578
Members
45,052
Latest member
LucyCarper

Latest Threads

Top