Вы находитесь на странице: 1из 260

Struts FAQ From jGuru

Generated Sep 13, 2005 2:24:14 PM

Location: http://www.jguru.com/faq/Struts
Ownership: http://www.jguru.com/misc/user-agree.jsp#ownership.

Why do we need Struts?


Location: http://www.jguru.com/faq/view.jsp?EID=469785
Created: Aug 5, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

Java technologies give developers a serious boost when creating and maintaining
applications to meet the demands of today's public Web sites and enterprise
intranets. Struts combines Java Servlets, Java ServerPages, custom tags, and
message resources into a unified framework. The end result is a cooperative,
synergistic platform, suitable for development teams, independent developers, and
everyone in between.

Who wrote Struts?


Location: http://www.jguru.com/faq/view.jsp?EID=469786
Created: Aug 5, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

Struts was created by Craig R. McClanahan, and donated to the Apache Software
Foundation in May 2000. Craig actively leads the Struts project, and is also the lead
developer on the Tomcat 4.0 project. There are now several committers to the Struts
project, working cooperatively from around the globe. Other Java developers are
invited to contribute to the project. Struts is an Apache Jakarta project, with the
common mission to "provide commercial-quality server solutions based on the Java
Platform that are developed in an open and cooperative fashion".

How is Struts licensed?


Location: http://www.jguru.com/faq/view.jsp?EID=469787
Created: Aug 5, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

Struts is copyrighted software available under a "free-to-use-license" by the Apache


Software Foundation. The license appears at the head of every source code file. A
reference copy of the license is available here.

Is Struts compatible with other Java technologies?


Location: http://www.jguru.com/faq/view.jsp?EID=471929
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

Yes. Struts is committed to supporting industry standards. Our lead developer is a


member of JSR052, Sun's Expert group for developing a standard library of custom
JSP tags. A primary design criteria is that Struts must be compatible with Sun's J2EE
platform for corporate enterprises. In fact, Struts really acts as an integrator of Java
technologies, so that they can be used in the "real world".
Where can I get help with Struts?
Location: http://www.jguru.com/faq/view.jsp?EID=471930
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

The Struts package comes complete with a users guide to introduce people to the
framework and its underlying technologies. Various components also have their own
in-depth developers guide, to cover more advanced topics. Of course, standard
"JavaDocs" are included along with the full source code. The Strut's mailing list is
also very active, and welcomes posts from new users. As a testament to its growing
popularity, Struts users are also posting their own tutorials and resource pages,
including those at Husted dot Com and Bluestone Software. Articles about using
Struts have appeared in JavaWorld, InformIt, and JavaReport. MyWebAppCarbaret
also offers free hosting of Struts applications, complete access to a MySQL database.

Where I can I get a copy of Struts?


Location: http://www.jguru.com/faq/view.jsp?EID=471931
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

The best place to download Struts is at jakarta.apache.org/struts. The nightly builds


are very stable, and recommended as the best place to start today.

How do I install Struts?


Location: http://www.jguru.com/faq/view.jsp?EID=471932
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

To develop applications with Struts, you can usually just add the Struts JAR file to
your Java development environment. You can then start using the Struts classes as
part of your own application. A blank Struts application is provided, which you can
just copy to get a quick-start on your own brainchild. Since the full source code for
Struts is available, we also provide complete instructions for compiling your own
Struts JAR from scratch. (This is actually easier that it looks!) Your Struts application
can be usually be deployed using a standard WAR file. In most cases, you simply
deposit the WAR file on your application server, and it is installed automatically. If
not, step-by-step installation instructions for various servlet containers are available.
Comments and alternative answers

my "no" vote was not counted ?


Author: Onno Kreuzinger (http://www.jguru.com/guru/viewbio.jsp?EID=1160336),
Apr 5, 2004
and i voted no because the link to the example on how to install in app. servers was
dead...

When do I need "struts.jar" on my classpath?


Location: http://www.jguru.com/faq/view.jsp?EID=471933
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)
When you are compiling an application that uses the Struts classes, you must have
the "struts.jar" on the classpath your compiler sees -- it does not have to be on
your CLASSPATH environment variable. Why is that an important distinction?
Because if you are using a servlet container on your development machine to test
your application, the "struts.jar" must not be on your CLASSPATH environment
variable when running the ontainer. (This is because each Web application must also
have their own copy of the Struts classes, and the container will become confused if
it is on the environment path as well.) There are several general approaches to this
issue:

• Use ANT for building your projects -- it can easily assemble classpaths for
the compiler. (This is how Struts itself is built, along with Tomcat and most
other Java-based projects).
• Use an IDE where you can configure the "class path" used for compilation
independent of the CLASSPATH environment variable.
• Use a shell script that temporarily adds struts.jar to the classpath just for
compilation, for example
javac -classpath /path/to/struts.jar:$CLASSPATH $@

Comments and alternative answers

struts.jar on my CLASSPATH
Author: Stjepan Brbot (http://www.jguru.com/guru/viewbio.jsp?EID=1161395), Apr
8, 2004
I need a better explanation why struts.jar must not be in my CLASSPATH and in
compiler's classpath in the same time. I work with JBuilderX+JBoss and I had some
troubles configuring all these paths. Now I have struts libs in JBuilder's CLASSPATH
and also have it in JBoss containers lib directory (it's classpath for compilation).
When I define in JBuilder that I want all struts components to be included in my
WAR (/WEB-INF/lib) I get an error message!

How do I authenticate users with Struts?


Location: http://www.jguru.com/faq/view.jsp?EID=471934
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

You can use either container-based security or form-based security to authenticate


users. With container-based security, the Web browser will track the logins for you,
and "replay" the credentials to the server whenever they are required. If a browser
hasn't been authenticated yet, it will automatically display a simple login form. If the
login passes, the user's original request will proceed. This will also work properly if a
user tried to POST from a form to an action URI in a protected area. Once the
browser is authenticated, the POST proceeds normally. For applications that manage
their own logins, it is probably easier to insist that every single page test for an
authenticated user first, and redirect to the login page if not. The Struts example
application does this -- partially by use of an application-specific custom tag
(app:checkLogon) that performs this check at the top of every page. The tag is
application-specific, because the notion of what constitutes a "logged on user" is
application specific as well.
Comments and alternative answers
more info on container-based security
Author: Randy Pond (http://www.jguru.com/guru/viewbio.jsp?EID=487474), Aug 30,
2001
Can someone provide more information about container based security? <- noobie
alert

thanks!

Another authentication option is Servlet 2.3 Filters


Author: Ryan Hoegg (http://www.jguru.com/guru/viewbio.jsp?EID=1027426), Nov
19, 2002
If you find that container based authentication is too restrictive and you don't want to
check for authentication credentials in each and every servlet, you can use Filters and
RequestDispatcher forwarding to accomplish any custom authentication goals.

Container authentication
Author: Stjepan Brbot (http://www.jguru.com/guru/viewbio.jsp?EID=1161395), Apr
8, 2004

There's stated that in container-based security model web browser tracks the logins -
is that correct?

As far as I know in container-based security one have the oportunity to define


realms/principals and users belongig to these principals. Also in configuration file of
your web application you can define restrictions which part of your application can
used by particular principal. When you try to access this restricted area of application
container will ask for authentication, upon sending right credentials (checked by
container according to defined rules in configuration files) it will create SESSION
with these credentials. Since your browser is connected with this SESSION (residing
on server) through cookies or URLrewriting every following try to access restricted
area will be successfull since container looking at user's session knows that this user
(browser) has been already authenticated.

So, is this security managed by browser or by container?

More info please on this topic. can you suggest links where this topic is described
in detail
Author: Lakshmi Mohan (http://www.jguru.com/guru/viewbio.jsp?EID=1225552),
Feb 7, 2005
More info please on this topic. can you suggest links where this topic is described in
detail

Can I use precompiled JSPs with Struts?


Location: http://www.jguru.com/faq/view.jsp?EID=471935
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

There is nothing about Struts that would care about precompiled versus not
precompiled JSP pages, but the details of how you set them up depends on the
servlet container you are using. With Tomcat, for example, running the "jspc"
command line tool will compile all your pages, but it will also create a bunch of
lt;servlet> and <servlet-mapping> tags that need to go into your web.xml file. In
particular (at least for Tomcat), though, the path of a JSP page does not change
when you use precompiled pages. The reason this works is that the compiler
generates a servlet mapping for "/jsp/awsMain.jsp" for you -- and, because this is an
exact match, it has higher priority than extension mapping on "*.jsp", which would
send the page back to the JSP servlet. Try leaving the path for the compiled case the
same as the path for the uncompiled case, and make sure that you've included the
necessary stuff in web.xml.

Can Struts be used in a commercial product?


Location: http://www.jguru.com/faq/view.jsp?EID=471936
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

Yes. The only requirements you must meet are those listed in the Apache Software
Foundation license, which is included at the top of each source file and in the file
LICENSE in the top-level directory of the distribution. In addition, contributions of
patches, improved code, new features, or even just requests for features are also
welcome.

How can I contribute to the development of Struts?


Location: http://www.jguru.com/faq/view.jsp?EID=471937
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

Struts is distributed by the Apache Software Foundation. These are the same people
who distribute the Apache Web server. Like all ASF projects, Struts is managed as a
"meritocracy", where everyone's contribution is welcome. Users can help other users
on the mailing lists, report bugs, and request new features. Developers can
contribute patches, new code, and documentation. The most active Developers may
become Committers, who make the actual decisions about the Strut's codebase. You
can start by joining the Struts User list. If you enjoy participating there, then sign up
for the Struts Developer list too. If you find any problems with Struts, or find a
missing feature, you can enter a record to our Bugzilla database.

What's the difference between Jakarta Struts and Jakarta Turbine?


Location: http://www.jguru.com/faq/view.jsp?EID=471938
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

See:

• < http://www.mail-archive.com/struts-
user@jakarta.apache.org/msg03206.html >
• < http://www.mail-archive.com/general@jakarta.apache.org/msg00495.html
>
• < http://jakarta.apache.org/velocity/ymtd/ymtd.html >

Is there a large degree of XML in Struts? Can you swap a stylesheet and
switch form HTML to WML?
Location: http://www.jguru.com/faq/view.jsp?EID=471939
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

The Struts form tags are very much HTML oriented, because they only know how to
generate HTML-style forms. One of the major focuses of 1.1 will be better integration
with XML in many directions, including an investigation of using things like XPath,
XForms, and so on. For integrating XSLT transformations, I would suggest utilizing
the "xsl" tag library in the Jakarta Taglibs project
<http://jakarta.apache.org/taglibs>. The <xsl:apply> tag is very powerful and
flexible, and can interoperate with Struts cleanly.
Comments and alternative answers

Is there a large degree of XML in Struts? Can you swap a stylesheet and switch
form HTML to WML?
Author: Raffi Sarkissian (http://www.jguru.com/guru/viewbio.jsp?EID=1109935),
Aug 20, 2003
We just recently implemented a system where we did not bother in using the Struts
supplied tags. Instead we opted on using the xtags xsl tag library. In a nutshell, we
took advantage of the struts framework, complemented it with XML and rendered all
in XSL using xtags. The performance is better then expected, JSP logic was minimal
and this allowed us to use the concept of “skins”. The output is adoptable not only to
various clients (ASP model), but also to various devices (WML e all).

>Why aren't the Struts tags maintained as part of the Jakarta Taglibs
project?
Location: http://www.jguru.com/faq/view.jsp?EID=471940
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

At first, it was to make it easier to develop the tags as the rest of the framework was
developed. Placing the tags in another repository would mean that we would have to
be more careful about changes and deprecations as people would be using them in
other environment. Once the set of standard tags is published (this is in progress
now), we will refactor the Struts tag libraries, and offer the remaining multi-use tags
to Jakarta taglibs.

How can I set the locale for each individual user session before the first
page displays? I've tried putting the
session.setAtttribute(Action.Locale_key,<locale>) but it always displays in
the default locale of the machine? Changing the machine locale causes the
correct properties file to be used so I know that is not the problem.
Location: http://www.jguru.com/faq/view.jsp?EID=471941
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

In the Struts example app, this is done by including the following tag on the
index.jsp page (actually, on every page):

<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>


<html:html locale="true">
... page content ...
</html:html>

This causes that <html:html> tag to consult the "Accept-Language" header sent by
the browser, and set up a Locale in the user's session if it is not already there --
exactly the same way that the controller servlet does this if you configure it to.
NOTE: There are currently problems with this on servlet containers that do not
correctly implement the JSP 1.1 requirements for converting custom tag attribute
values. We have heard problem reports about JRun 3.0 and ATG in this regard.

Comments and alternative answers

Curiosly!
Author: Rajesh Kini (http://www.jguru.com/guru/viewbio.jsp?EID=1008998), Nov
11, 2002
I am using the <html:html locale=true> tag.

My IE browser is set with the language en-us, but all my pages show <html
lang="en">

I tried it out with Netscape 7.0, with en-us set first and en set second, still, the same
result from the page.

I wonder why that is so!

Re: Curiosly!
Author: Jothibasu Ramachandran
(http://www.jguru.com/guru/viewbio.jsp?EID=1083851), May 12, 2003
The language is selected using the Locale value that is conforming to the ISO list
for country codes. As per that the country/Locale is specified with a "2 char" code.
That could be the reason why it is taken so. Please check with the Locale code
listing in the web to find the code for en-us.

the answer
Author: Aleksey Skorokhodov
(http://www.jguru.com/guru/viewbio.jsp?EID=965496), Jun 20, 2003
I had the very same problem. the solution is VERY simple :) you need to restart
our browser after changing your locale. it helped me
Re: Curiosly!
Author: Stjepan Brbot (http://www.jguru.com/guru/viewbio.jsp?EID=1161395),
Apr 8, 2004
According to Ted Husted's book "STRUTS in Action" STRUTS framework uses
only country code (first two letters in Locale string) meaning that for STRUTS
"en", "en_gb" and "en_us" are the same thing, the same Locale "en".

I have a simple question about localisation: If there is multiple users using


the same localisation parameters : do they share a common
ResourceBundle instance or do they have their own one. It seems to me
that each user has his own ResourceBundle instance but does that affect the
performance of the application.
Location: http://www.jguru.com/faq/view.jsp?EID=471942
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

The application's message resource bundles are shared across all of the users of a
particular Struts-based web application. The only thing that is unique to a particular
user is the java.util.Locale object (stored in the user's session) that represents his or
her current Locale preferences.
Comments and alternative answers

SubQuestion
Author: Stjepan Brbot (http://www.jguru.com/guru/viewbio.jsp?EID=1161395), Apr
8, 2004
So if I have ResourceBoundle.properties and ResourceBoundle_hr.properties,
container creates two objects in memory (one for each properties file) and shares
these two object among many users. Is that correct?

Re: SubQuestion
Author: Esteve Olm (http://www.jguru.com/guru/viewbio.jsp?EID=1171236), Jan
28, 2005
Yes, it is

Why can't the Struts tags access the properties of my beans?


Location: http://www.jguru.com/faq/view.jsp?EID=471943
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

Struts uses JavaBeans Introspector to discover properties of beans. Introspector is


pretty picky in the way it decides whether something is a property or not.
Specifically, it requires that

1. Both getter and setter be declared public and non-static


2. The return type of the getter be the same as the type of the argument of the
setter.

So, first check if your property breaks one of these rules.


Comments and alternative answers

More requirements
Author: Giri M (http://www.jguru.com/guru/viewbio.jsp?EID=971868), Nov 19, 2002
If the property name in Struts tag is called "password", then according to the Java
bean spec, the getter/setter should look like getPassword and setPassword. if u define
it as getpassword, it will not work!1

Another reason
Author: Jean-Carl AMSLER
(http://www.jguru.com/guru/viewbio.jsp?EID=1065682), Mar 13, 2003

If Struts debugger tell you that the property of a tag is unreachable and even if the
property exists (with a get method), it may the property get method returns "null"
value...

I usually need 'wrap="virtual"' as an attribute for my textareas. It isn't part


of the HTML spec, but it's supported in both Netscape and IE, and it's pretty
useful.
Location: http://www.jguru.com/faq/view.jsp?EID=471944
Created: Aug 8, 2001 Modified: 2001-10-27 01:52:10.919
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

The Struts Action works through introspection. It doesn't know (or care) whether the
value in a form was rendered by a Struts custom tag or not. This means if you use a
standard textarea tag in your form, and give it a name that matches a property in
your form bean, Struts will use that attribute just as if it had been rendered by a
html:textarea tag. After all, this is all the Struts html:textarea tag does. To seed the
textarea from the form bean, you could code something like:

<textarea name="article" rows="15" cols="60" wrap="soft"></textarea>

And everything else will be automagical again.

How do I use Javascript with my Struts forms?


Location: http://www.jguru.com/faq/view.jsp?EID=471945
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

The relevant HTML tags provide support for the Javascript event handlers onblur,
onchange, onclick, ondblclick, onfocus, onkeydown, onkeypress, onkeyup,
onmousedown, onmousemove, onmouseout, onmouseover, onmouseup.

For more about Javascript events, see the Netscape Javascript Reference guide.

For more about HTML tags, see the Struts HTML Tag Guide.
As usual, the Javascript itself can then be placed:

1. Inline, if it is simple enough, like onclick="history.go(-1)"


2. As a <SCRIPT> within your JSP
3. As an included <SCRIPT src="my.js"> to your JSP

Note that the Struts Javascript properties use all lowercase identifiers, for XML
compatibility.

Comments and alternative answers

Struts and javascript


Author: Candice Lohe (http://www.jguru.com/guru/viewbio.jsp?EID=793077), Mar
12, 2002
The <SCRIPT src="myfile.jsp" ></SCRIPT> works fine for regular jsps; however,
there doesn't seem to be a way of using it with templates. Any suggestions?

Re: Struts and javascript


Author: nicolas lavielle (http://www.jguru.com/guru/viewbio.jsp?EID=1125585),
Nov 11, 2003
If I want to use Javascript files in different languages, how can I do that ?
I can't use <SCRIPT srckey="mypath.inresourcebundle"></SCRIPT>
Any suggestions ?

How do I use Javascript to perform validation in Struts?


Location: http://www.jguru.com/faq/view.jsp?EID=471946
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

The best way is using David Winderfeldt's Struts validator servlet. This provides
seamless client-side and server-side validation using regular expressions.

Other than that, you can also attach other Javascript validation to the Struts form
fields using the provided properties for Javascript event handling. Of course, these
types of validations cannot be guaranteed if a browser has Javascript turned off.

Why doesn't Struts provide it's own facility for regex or Javascript validations?
David Winterfeldt's Validator is being integrated with Struts 1.1.

Is it possible to combine dynamic Javascript menu systems with Struts?


Location: http://www.jguru.com/faq/view.jsp?EID=471947
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

The challenge with doing this is that the JSP tags run on the server (as the page is
being generated), while the JavaScript runs on the client side. To integrate the two,
you need your tags (and other JSP code) to dynamically generate the JavaScript
functions themselves -- sort of having a program write a program -- so that the
JavaScript is customized to your particular need on this particular page. A very trivial
example is the way that the <html:form> tag deals with the "focus" attribute. If you
specify it, a dynamically generated bit of JavaScript is created to set the input focus,
which includes the name of the field you want initial focus assigned to. For a more
comprehensive scenario, consider that for most menuing systems you will need to
configure the list of available options into a JavaScript array or something. You could
use the <logic:iterate> tag to render the elements that get set in the array's
initialization expression.
Comments and alternative answers

struts rollover example


Author: dmitry amelchenko (http://www.jguru.com/guru/viewbio.jsp?EID=877173),
Mar 11, 2003
The article explains things very well, it's just too high level though. If a simple
example of how does a rollover javascript work with struts <html:image> can be
provided, it would make life much easier.

Under Netscape 4.7 for Windows, the html:form focus feature doesn't work
properly. Is there a work around?
Location: http://www.jguru.com/faq/view.jsp?EID=471948
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

The problem is that the focus feature works all right at first, but when you press tab,
it proceeds to the address bar, rather than the next field. After you tab around once,
it starts working as expected. One work around is to use the "onblur" event on the
initial field to select the second. After that, Bob's your uncle!

Example:

<html:form action="/logon" focus="username">


<p>Username <html:text property="username"
onblur="this.form.password.focus();"/>
<p>Password <html:password property="password"/>
<p><html:submit property="submit" value="SIGN IN" />

To focus the first field on the first form, you can also do this

<body onload="document.forms[0].elements[0].focus();">

in all your form pages rather than use the Struts html:form focus property.

Is the Struts object-orientated appropriate for small, heavily-loaded


servers?
Location: http://www.jguru.com/faq/view.jsp?EID=471949
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

Compared to embedding the application logic in your servlet, Struts doesn't cost very
much in terms of object creation. Struts only creates an instance of an Action class
once, and then reuses it continually. You will also find that, with more recent JVMs,
object creation overhead has been dramatically reduced -- it may not longer be the
dominant factor in performance. ActionForm beans in Struts can be stored in the
user's session (this was the original design), but also as request attributes. This is
particularly useful when the entire form is displayed on one page, and the page
contains every property as either a hidden field or a visible field. In such cases, there
is no need to keep the form bean instance around in between requests. At the end of
the day, though, you have to have an incredibly small server for the performance
issues like single object versus lots of objects matter very much.

Does anyone know the performance difference between a direct method call
andintrospection like Struts uses?
Location: http://www.jguru.com/faq/view.jsp?EID=471950
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

Independant performance engineers have benchmarked JDK 1.3 and the difference is
now insignificant.
Comments and alternative answers

Are benchmarking results available on-line?


Author: Roman Pozlevich (http://www.jguru.com/guru/viewbio.jsp?EID=225725),
Aug 24, 2001
I'm curious about the benchmarking results. Can somebody provide links where I can
see them?

Can we configure a separate log for each application?


Location: http://www.jguru.com/faq/view.jsp?EID=471951
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

There is a restriction in Tomcat 3.2 related to how you declare log files. In Tomcat
4.0 this has been enhanced, letting you declare a separate destination for the servlet
log per application, instead of globally. If you need to run under Tomcat 3.2, I
suggest that you add some sort of application identifier to the log messages being
created. A common pattern creates log files like this:

[Application1] This event happened


[Application2] That other event happened

Is there is some kind of "j2ee compliant" way of doing user authentication


and role-assignment - are there any standards one is supposed to use?
Location: http://www.jguru.com/faq/view.jsp?EID=471952
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

The J2EE recommendation for this is to use container-managed security (i.e. the
<security-constraint> elements defined in web.xml) for user authentication and
access control. Doing so means that the container is taking care of these issues for
you, and (perhaps more importantly) that user identities are shared between the
web layer and the EJB layer, because the server will be using the same underlying
"database" of users and roles.

The only downside to this approach is that there is not yet a standardized API for
portably accessing and maintaining a "database" of users and roles ("database" is in
quotes because the actual implementation could be anything, including static text
files or directory servers).

Instead, most servers provide a server-specific API to do this kind of thing. For
example, in Tomcat you can implement an API called a Realm that talks to your
existing database of users, and then tell Tomcat to use this Realm implementation
for user authentication. In that way, new users added to the database (by whatever
means) become instantly authorized for web use also. If you were to switch to a
different engine, you would need to re-implement this function according to the APIs
provided by the new server, but you would not need to update your applications.

Comments and alternative answers

Container-managed security
Author: Mitch Dresdner (http://www.jguru.com/guru/viewbio.jsp?EID=390316), Feb
14, 2002
When using container managed security (in Catalina), is there anyway to logoff?

Re: Container-managed security


Author: Matt Johnson (http://www.jguru.com/guru/viewbio.jsp?EID=141820),
Feb 26, 2002
Invalidate the session

Re[2]: Container-managed security


Author: Mitch Dresdner
(http://www.jguru.com/guru/viewbio.jsp?EID=390316), Feb 27, 2002
Matt,

I was using Basic Authentication and invalidating the session wouldn't work.
Works fine for forms. I found the following in one of the Tomcat specs:

"Once a user has been authenticated, the user (and his or her associated roles)
are cached within Tomcat for the duration of the user's login. (For FORM-
based authentication, that means until the session times out or is invalidated;
for BASIC authentication, that means until the user closes their browser). Any
changes to the database information for an already authenticated user will not
be reflected until the next time that user logs on again."

Thanks for taking time to reply.

Regards,

Mitch
Re[3]: Container-managed security
Author: Matt Johnson
(http://www.jguru.com/guru/viewbio.jsp?EID=141820), Feb 27, 2002

RFC2616 states that

If the request already included Authorization credentials,


then the 401 response indicates that authorization has been
refused for those credentials. If the 401 response contains
the same challenge as the prior response, and the user agent
has already attempted authentication at least once, then the
user SHOULD be presented the entity that was given in the
response, since that entity might include relevant
diagnostic information.

Although this is kind of open to interpretation, IE5 for one sees an


additional 401 Unauthorized response, after credentials have been
presented, as an indication that the credentials have expired, and the user is
presented with a new prompt.

If you use the Jakarta response taglib, the following will work:

<response:addHeader name="WWW-Authenticate">Basic
realm="Your Realm Name"</response:addHeader>

<response:sendError error="SC_UNAUTHORIZED">Credentials have


expired</response:sendError>

Obviously, this should only be returned until the user has been re-
authorised.

In the end, this removes some of the power of the deployer by hardcoding a
Realm name, etc. There may be other ways to ensure expiry in the
Container-Managed Security method you use, returning similar HTTP
return code and header as described above.

HTH - Matt J.

How can you prevent users from accessing a JSP directly that is designed to
be used from an Action?
Location: http://www.jguru.com/faq/view.jsp?EID=471953
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

Put those JSP pages in a directory under WEB-INF; for example, WEB-INF/jsp. Files
under the WEB-INF directory cannot be directly accessed. Another approach is
supported by the servlet API if you are using container-managed security for your
application. You can define a security constraint that lists no roles as being allowed,
which the servlet container will interpret as not allowing access to anyone directly
from a request. You can forward to (or include) such a page -- just not request it
directly.

Note that this behavior was not clearly specified in the 2.2 servlet spec, so your
mileage might vary there -- but all 2.3 containers are required to act this way.

Consider the following security constraint:<security-constraint>

<web-resource-collection>
<web-resource-name>All JSP Pages</web-resource-name>
<url-pattern>/pages/*</url-pattern>
</web-resource-collection>

In a servlet 2.3 container (such as Tomcat 4.0), this is interpreted to mean that
there is no direct access at all to any URL like:

http://localhost:8080/myapp/pages/menu.jsp

but you are allowed to use a request dispatcher to access them. This is because
security constraints are to be checked only on the *original* URL, not on the
forward/include. Thus, if you want to ensure that a page is accessed only via the
controller servlet, you can give it a URL path within the "pages" subdirectory, and the
container will take care of this for you.

Comments and alternative answers

How do you address JSPs under WEB-INF/jsp? I thougt this wasn't possible?
Author: frank prumbaum (http://www.jguru.com/guru/viewbio.jsp?EID=578394),
Dec 10, 2001
?

Re: How do you address JSPs under WEB-INF/jsp? I thougt this wasn't
possible?
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042), Dec
30, 2001
Most containers allow servlets to forward to a JSP under WEB-INF, and I have it
from good authority that this is the intended behavior. Some containers, notably
WebLogic, choose not to implement this feature. -T.

Re[2]: How do you address JSPs under WEB-INF/jsp? I thougt this


wasn't possible?
Author: Sken Malkowitch
(http://www.jguru.com/guru/viewbio.jsp?EID=898662), May 31, 2002
Hi Ted, I'm using WebLogic Ver 5.1.0 and now I want to develope some
applications with Struts. Can you tell me if this or some newer versions of
WebLogic implement this great feature? If so, can you tell me which versions
are implementing it. TNX

Re[3]: How do you address JSPs under WEB-INF/jsp? I thougt this


wasn't possible?
Author: Matt Cox (http://www.jguru.com/guru/viewbio.jsp?EID=885298),
Jun 3, 2002
<security-constraint>
<web-resource-collection>
<web-resource-name>All JSP direct access</web-
resource-name>
<url-pattern>private/*</url-pattern>
<http-method>POST</http-method>
<http-method>GET</http-method>
</web-resource-collection>
<auth-constraint>
<description>
No Access
</description>
<role-name>restricted</role-name>
</auth-constraint>
</security-constraint>

<login-config>
<auth-method>FORM</auth-method>
<form-login-config>
<form-login-page>error.html</form-login-page>
<form-error-page>error.html</form-error-page>
</form-login-config>
</login-config>

<security-role>
<description>NO Access</description>
<role-name>restricted</role-name>
</security-role>
My error.html simply has one word: DENIED. It's a bit of a hack but it
works. I dont' see why there couldn't be another auth-method added that
simply refused access with a 403 response. After moving my private jsp
pages to the private path (all but the logon.jsp) I needed to modify the
struts-config.xml to correct map the action for inputs and forwards to the
new location.

How do you implement the security constraint to allow no JSP direct access?
Author: Bobby Lewis (http://www.jguru.com/guru/viewbio.jsp?EID=715163), Jan 9,
2002
How do you implement: <security-constraint> <web-resource-collection> <web-
resource-name>All JSP Pages</web-resource-name> <url-pattern>/pages/*</url-
pattern> </web-resource-collection> This means that noone (no logins) can access
any files under /pages/. Where is this code placed? In the web.xml or the struts-
config.xml file? Or elsewhere? Thanks. Bobby Lewis

Re: How do you implement the security constraint to allow no JSP direct
access?
Author: Bobby Lewis (http://www.jguru.com/guru/viewbio.jsp?EID=715163), Jan
9, 2002
Actually, I'm working with the struts-examples application in Tomcat 4.0 on
Windows 2000. I put this:
<security-constraint>
<web-resource-collection>
<web-resource-name>placeorder</web-resource-name>

<url-pattern>/*.jsp</url-pattern>
<http-method>POST</http-method>
<http-method>GET</http-method>
</web-resource-collection>
</security-constraint>

in the web.xml in the WEB-INF subdir of the struts-examples app. When I restart
Tomcat, I get:
PARSE error at line 92 column 11
org.xml.sax.SAXParseException: The content of element type "web-
app" must match
"(icon?,display-name?,description?,distributable?,context-
param*,servlet*,servl
t-mapping*,session-config?,mime-mapping*,welcome-file-list?,error-
page*,taglib*
resource-ref*,security-constraint*,login-config?,security-
role*,env-entry*,ejb-
ef*)".
Everything seems right. Any ideas?

Re[2]: How do you implement the security constraint to allow no JSP


direct access?
Author: Devinder Singh
(http://www.jguru.com/guru/viewbio.jsp?EID=141755), Mar 12, 2002

The elements you choose to include in your web.xml should


follow the listed element order in the error message. The
parser expects them in a specific order.

Re[2]: How do you implement the security constraint to allow no JSP


direct access?
Author: Prasad Javdekar
(http://www.jguru.com/guru/viewbio.jsp?EID=1189769), Jul 31, 2004
Hi Bobby,
Your <security-constraint> element looks fine, true, but check the
sequence of all the web.xml elements. The error you got indicates that you
might have wronged the "sequence".

regards.

Security of JSP Pages


Author: Robert Nicholls (http://www.jguru.com/guru/viewbio.jsp?EID=527915), Jan
24, 2005

This is a little off the topic but it is the reverse problem. I an using container managed
security under Tomcat. It works well except when I pop up a new window for "help".
This is an active page (JSP). It seems that Tomcat sees a new session for the window
and insists that the application log in again for the popup.

Short of fiddling with the security signature (<url-pattern> ) is there some way to
keep the new windows within the same session and thus obviate the need for a new
login on the popup?

Thanks,
Bob N-

Using action classes as adapters and session EJBs for business logic sounds
like a good way to go. Is also using EJBs as actionforms is a good idea
because they are a good target for object reuse/
Location: http://www.jguru.com/faq/view.jsp?EID=471954
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

ActionForms are not designed for reuse with an EJB. In fact, early on, the ActionForm
was changed from an interface to an abstract class to discourage this idea.

The reasoning goes like this:

• An ActionForm is part of the view layer of MVC, not the model layer like an
EJB (or a regular JavaBean that represents persistent data).
• The sole purpose of an ActionForm is to maintain the state of all the input
variables on a particular form, so that you can reproduce the form pre-filled-
in if the user made an error that they need to fix. This matches the
expectations of users who are used to GUI-based client server apps, that
never make you retype any input except the stuff you did wrong.
• Because of the above, the "domain" of an ActionForm does not necessarily
match any existing EJBs or model layer JavaBeans. It is not uncommon to
have inputs from a single form that will ultimately cause updates to more
than one undelrying EJB or model bean.
• Using a separate class for the ActionForm means you can change the
underlying organization of your model beans or EJBs without impacting the
view layer (although there might be modest impacts on the Action classes
that copy things back and forth).
• In addition, most EJBs and model beans have validation rules internally that
prevent them from accepting semantically invalid data. Such rules would
prevent you from accomplishing the primary purpose of an ActionForm --
storing all of the user's input fields, so that you can reproduce the input
screen.
• Also, if your form is multiple pages and you were using the real EJB, let's say
you start updating properties based on receiving the first page. Now, you've
potentially started locking resources in the underlying database -- and you
have to deal with the fact that the user may never come back and finish this
transaction.

So, the bottom line recommendation is that you plan on building simple JavaBeans
for your ActionForms. Most of the time, an ActionForm will have just getters and
setters, with no error checking (other than a validate() method if you want to use it,
plus the reset() method). PropertyUtils also has a convenience function that can copy
properties with like names from your EJB to the ActionForm bean (or vice versa), to
reduce the amount of tedious code that this approach implies. And, at some future
point, it's reasonable to expect a development tool to be able to auto-generate
ActionForm beans for you.

Using an EJB as a bean that provides data values used in the presentation, on the
other hand, is pretty easy. Just store the client-side instance you get back from the
EJB server as a request attribute or session attribute -- from the perspective of the
Struts custom tags, this EJB just looks like a JavaBean with getter methods, so they
don't care that it is really an EJB. NOTE: If the EJBs are really on a remote server
this could have some performance impact -- you might be better served to copy data
into local beans in that case.

Why is the form bean automatically created by both servlet and form tag?
Location: http://www.jguru.com/faq/view.jsp?EID=471955
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

It is valid for a user to enter the system either through the servlet or through the JSP
form, and so the bean must be created in either place.

How can you tell if a form bean was automatically created?


Location: http://www.jguru.com/faq/view.jsp?EID=471956
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

In general, you can define a special member variable in the bean that indicates that
it has just been created. On a manual create you would reset that yourself, but on an
auto create it would remain set, and the validate method would detect it (or you
could check manually).

Reset for validation


Location: http://www.jguru.com/faq/view.jsp?EID=471957
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

There is a reset() method on ActionForm that is called *before* Struts does the
auto-populate trick. The contract is that this method should reset all relevant
attributes for this particular form to default values. For checkboxes, you would want
to set the corresponding boolean to false. It will be set to true by the auto-populate
method *if and only if* the checkbox was checked (and therefore included in the
POST).

For integers, it is technically feasible to distinguish an empty field ("") versus a zero
("0"). If we decide not to call the setter in this scenario, then the ActionForm
property will remain at it's default value, so you can distinguish whether it was
entered or not.

On the other hand, we could take the approach that the form should have displayed
the default value in the first place, and the user would have had to erase the existing
value to cause an empty string to be posted -- and that the bean should want to
know about that. Because we have to generate a legal integer value, the decision is
what value to use for indicating "no input". Zero is the current mechanism for this,
but it's not the only choice.

Comments and alternative answers

Checkbox resetting in general...


Author: Jeff Hamilton (http://www.jguru.com/guru/viewbio.jsp?EID=791422), Mar
13, 2002
I've got a question regarding the best way to handle checkboxes and resetting them.
My requirement is that the form is in the session (so it can be returned to easily) and
that the checkboxes maintain their appropriate values.
If I include code to set them to false in the reset() method of the form, the form
behaves properly while I am posting on that page.
But, when I return to that page from another page, Struts has reset all my checkboxes
to false (off).
If I don't include the reset() code, then the values are maintained properly between
pages but not within posts on that page.
What's the best way to solve this problem?

Re: Checkbox resetting in general...


Author: Alice Howell (http://www.jguru.com/guru/viewbio.jsp?EID=910261), Jun
11, 2002

At http://jakarta.apache.org/struts/newbie.html there is a question "Why are my


checkboxes not being set from ON to OFF?"

The answer states: "If the value of the checkbox is being persisted, either in a
session bean or in the model, a checked box can never unchecked by a HTML
form -- because the form can never send a signal to uncheck the box. The
application must somehow ascertain that since the element was not sent that the
corresponding value is unchecked."

It also states to possibly use a radio button. I am in the process of trying to make
this work because I am keeping my form in the session. I am going to try to see if
I can check for the element being sent.
Alice

Re[2]: Checkbox resetting in general...


Author: Chris Felaco (http://www.jguru.com/guru/viewbio.jsp?EID=281872),
Jun 8, 2004

There is a very simple solution to the checkbox problem. The trick is to always
add a hidden field AFTER the checkbox with the same parameter name but
with the value set to "false":

<html:checkbox property="booleanProperty" value="true" />


<input type="hidden" name="booleanProperty" value="false">

Basically, the hidden parameter ensures that there is some request parameter
submitted, which will always set the corresponding ActionForm property. If
the checkbox is checked, the 2 parameters will be passed:
"booleanProperty=true&booleanProperty=false". But the beanutils code only
uses the first parameter to set the value. If the checkbox is left unchecked, then
there will be only 1 parameter "booleanProperty=false" which will ensure the
property is set.

The HTML spec says that form elements must be submitted in the GET or
POST in the order that they are specified in the HTML, and all browsers I have
used obey this rule. There is no risk that the hidden parameter will obscure the
form field as long as you always put it after the checkbox.

The beauty of this solution is that it places the burden in the hands of the page
author where there can be more flexibility. It also allows the page author to
invert the meaning of the checkbox without bothering the application
developer. All the page author needs to do is reword the caption, and switch
the ordering of the values used in the checkbox and hidden fields. Also, it
works with string or numeric properties just as easily.

Re[3]: Checkbox resetting in general...


Author: Aaron Mapes
(http://www.jguru.com/guru/viewbio.jsp?EID=1202934), Oct 1, 2004
Brilliant solution, very simple indeed, and I scoured the net for hours on
ways to do this that didn't involve subclassing the DynaValidatorForm
class. This work around really should be easier to find, or added to a Struts
FAQ somewhere...

Re[4]: Checkbox resetting in general...


Author: Miles Daffin
(http://www.jguru.com/guru/viewbio.jsp?EID=1213072), Nov 25, 2004
Hear hear! Me too. For hours.... What a relief! Thanks Chris.

Re[3]: Checkbox resetting in general...


Author: Emory Smith
(http://www.jguru.com/guru/viewbio.jsp?EID=1213312), Nov 27, 2004
thank you chris!!

Re[3]: Checkbox resetting in general...


Author: Nishi Shah
(http://www.jguru.com/guru/viewbio.jsp?EID=1221411), Jan 16, 2005
This is not a good solution at all. It is just a work around. This solution will
fail when you want to call javascript function on clicking of the checkbox.
The correct solution is :- override the "reset" method in the form bean and
set the checkbox value false to correctly identify the checkbox value from
request. If your bean is in session scope and if you don't want to identify
the correct value everytime then get the action from request object and
set/reset the checkbox value.

Re[4]: Checkbox resetting in general...


Author: Justin Galzic
(http://www.jguru.com/guru/viewbio.jsp?EID=1221739), Jan 17, 2005

A way to accomplish what you want without any "hacks" to your jsp/ui
is by extending the DynaValidatorForm and creating your own reset
method (you don't need to override anything else). In addition to calling
super.reset, you need to change the property value of your checkbox
used by the DynaValidatorForm's map.

reset looks like this:

super.reset(actionMapping, httpServletRequest);

Map map = getMap();


if (map.containsKey("checkbox_prop_name")
{
map.put("checkbox_prop_name", Boolean.FALSE);
}
This works well for me without having to make any changes to my
presentation layer. Justin
Re[4]: Checkbox resetting in general...
Author: hal taylor
(http://www.jguru.com/guru/viewbio.jsp?EID=1230843), Mar 4, 2005
What do you do if you want the checkbox to default to true/checked?
You can have it set true in the FormBean's constructor, but then how do
you register the change to false if the user de-selects the checkbox?
How does reset() help with this? How do you tell if no value was
submitted? If you have defaulted the bean value to true, and the
checkbox is then deselected, the value for this field will not be
submitted, and therefore not get updated to false, right? How does one
get around this problem when checkboxes should be true by default? In
my case, javascript is not an option....

Re[5]: Checkbox resetting in general...


Author: Assaf Berg
(http://www.jguru.com/guru/viewbio.jsp?EID=1234912), Mar 27,
2005
I've had this problem as well. You can't set the checkbox value to
true in reset() because then it will stay on for ever. What I did is
added a method called setup() to the form, that applies default
values to fields (such as checkboxes that need to be checked). The
setup method is called only when the form is initialized, so if the
user changes the checkbox value it is not overridden by anything in
reset(). In order to only call setup() in initialization i've added a
hidden field to the JSP with a certain predefined value (doesn't
matter which, i used the string 'true' because I called that field
initialized). When the Action that prepares the form is called first,
'initialized' won't be set. Only after submitting the form its value
will change to true. in the validate() method of the form I call
setup() only if initialized != true.

Re[4]: Checkbox resetting in general...


Author: Mark Salamon
(http://www.jguru.com/guru/viewbio.jsp?EID=589110), May 23, 2005
You can get this to work. B/c you have two elements with the same
name, you can get an array of those values
(http://docs.sun.com/source/816-6408-10/form.htm), then just pick the
element you want and work with that. I did it like this, where the first
time elementX is listed on the page it's the checkbox and the 2nd time
it's the hidden field:

// get array of items with the same name


var arr = document.forms[0].elementX; var arr0 = arr[0]; // the
checkbox
var arr1 = arr[1]; // the hidden property
// see if checkbox is checked
if(arr0.checked == true)
{ var c = confirm('Are you sure?');
// if not sure, reset checkbox to false
if(!c)
{
arr0.checked = false;
}
}

Re[3]: Checkbox resetting in general...


Author: deep sekhar
(http://www.jguru.com/guru/viewbio.jsp?EID=1224723), Feb 2, 2005
Thanks Chris, I was trying for the same and was fighting a lot for the
solution, Thanks for solution i was relieved

Re[2]: Checkbox resetting in general...


Author: andrea castagnini
(http://www.jguru.com/guru/viewbio.jsp?EID=1248934), Jun 16, 2005
Thank you Chris

Re[3]: Checkbox resetting in general...


Author: richmond te
(http://www.jguru.com/guru/viewbio.jsp?EID=1028257), Aug 4, 2005
thanks. good trick. but when writing jwebunit test, it fails with exception as
it doesnt allow you to assign a value of 'true' eg.
checkCheckbox("booleanProperty", "true"); results in exception - must
have the value of 'false'. Attempted to set it to 'true' any suggestions?
thanks again.

Does an Action have to return an ActionForwarding?


Location: http://www.jguru.com/faq/view.jsp?EID=471958
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

No. Sometimes, it might be better for an Action to handle the request itself. For
example, you might need to return dynamic content that would be impossible or
impractical to create with a JavaServer Page. Or, you might need to return content
using a special MIME type.

If the Action handles the request itself, and presents an appropriate view to the
client, it can return null to the controller.

How can Struts check for a set of global conditions before processing an
action?
Location: http://www.jguru.com/faq/view.jsp?EID=471959
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

This often comes up in the context of authenticating users or with other control flow
issues.

The direct approach would be to subclass the ActionServlet controller servlet, and
override a method like processActionPerform (which actually calls the selected
Action) or processActionForward (which forwards control to the returned logical page
name). You could then inspect the current state of the world, and inject flow-of-
control changes like this still utilizing the superclass's basic functionality.

To make the types of things you inject somewhat configurable, you might also want
to use your own custom ActionMapping subclass, with extra bean properties that
describe (to your override method) what exceptional things to do and when to do
them -- the selected ActionMapping instance is made available to most of the
processing calls, so this information would be easily accessible.

If, as part of injecting control follow changes, you need to track where the user was
in your application, you might have your ActionServlet subclass maintain a request-
scope attribute with a well-known name, containing the value returned by
request.getServletPath(). This would act something like the "referer" header in an
HTTP request, and provide some history tracking.

Comments and alternative answers

Generic example of this?


Author: D parker (http://www.jguru.com/guru/viewbio.jsp?EID=871708), May 8,
2002
very interested in something like this in order to accomplish a work flow.

E.g., I would like to show a collection of database info on a splash page. This means I
have to check for the existance of the cached objects holding the db info and print
them. This means routing the request to already existing Actions and then back to the
index.jsp.

Unless there is an easier way to accomplish this, please provide an example of


subclassing the ActionServlet controller servlet to achieve a url sequence.

Thank you.

David

Other alternatives: 1) base Action class, 2) RequestProcessor (Struts 1.1)


Author: Jerome Jacobsen (http://www.jguru.com/guru/viewbio.jsp?EID=65688), Oct
3, 2002
Two alternatives to subclassing ActionServlet are: 1) providing a base Action class
and 2) subclassing RequestProcessor (new in Struts 1.1).
1) Base Action class: Provide a base Action class that all of your Action classes
subclass. Do your "global conditions" checking in the base Action's execute() method.
In the subclass Actions' execute() methods, first call the base Actions' execute(). Or
use a "method template" technique. Force all of the base Action subclasses to
implement an execute() "like" method, let's call it perform(). Then the base Action's
execute() would call perform() after doing it's custom stuff. And the subclass Actions
would not implement execute(), just perform().

2) Subclass RequestProcessor in a similar way as Ted described for subclassing the


ActionServlet. But must be Struts 1.1 or greater.

Re: Other alternatives: 1) base Action class, 2) RequestProcessor (Struts 1.1)


Author: Bill Newsom (http://www.jguru.com/guru/viewbio.jsp?EID=1169641),
May 10, 2004
The base action class technique is interesting, and I would like to use it. The
problem is the mapping of this base action so that it can handle ANY of the forms
that could be submitted to it. How would that be done?

How can I initialize custom "application scope" objects for use in a Struts
application?
Location: http://www.jguru.com/faq/view.jsp?EID=471960
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

One way would be to subclass the ActionServlet, to to initialize whatever application


scope objects you might need. Just remember to call the super.init() method!

A better approach would be to write another servlet, and auto-load both the Struts
controller and your own servlet through the web.xml file. The Example application
does this to load a "database" servlet, which is then accessed throughout the
application. This way you can initialize application-specific things through your
specialized servlet, and leave the normal Struts controller servlet alone.

In a servlet 2.3 environment (such as Tomcat 4.0), you will also be able to use the
new application event listener APIs to catch the contextInitialized() and
contextDestroyed() events. This will become the preferred method, once servlet 2.3
containers are widely available.

Comments and alternative answers

Best practice to access data source config?


Author: Niko Schmuck (http://www.jguru.com/guru/viewbio.jsp?EID=408882), Jan
28, 2002
The problem i found with the struts-example web application and the
DatabaseServlet (extends HttpServlet) is:
• how do i get the data source configuration from the file struts-config.xml
if the servlet is not inherited from ActionServlet, would you propose to
parse the config file on my own or is their a more convenient way?

Thanks, Niko.

how do I give an object 'application scope'?


Author: Dave Sag (http://www.jguru.com/guru/viewbio.jsp?EID=1043334), Jan 6,
2003
I have gone the first route with my project and can't find any docs that would show
me how I actually make my application scope objects visible to my actions? as my
shared data structure is about 50megs of read only data held in RAM for speed I don't
want every action to have it's own copy. hence the use of application scope vars.

your plan b is quite an interesting one. would you care to elaborate a bit or point me
to some docs I can read on this technique?

dave

Re: how do I give an object 'application scope'?


Author: Durga Rani (http://www.jguru.com/guru/viewbio.jsp?EID=1198025), Sep
8, 2004
Write a plugin which implements 'org.apache.struts.action.PlugIn' . Override the
init method to load the object in the application scope using
servletcontext.setAttribute API.

Re[2]: how do I give an object 'application scope'?


Author: John Green (http://www.jguru.com/guru/viewbio.jsp?EID=1258450),
Aug 17, 2005
I found setting app scope variable is most easily accomplished by writing a
struts plug in. Its very easy, just create a new class that implements
org.apache.struts.action.PlugIn and put as many of the following as
you need in the init(...) method:
actionServlet.getServletContext().setAttribute("key", value);
Then just add the following to your struts-config.xml file:
<plug-in className="path.to.class"></plug-in>
Done!

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).
Location: http://www.jguru.com/faq/view.jsp?EID=471961
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

You can 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.

Comments and alternative answers

How did i do that from within a servlet ??


Author: sulfura c (http://www.jguru.com/guru/viewbio.jsp?EID=823463), Apr 23,
2002
Iam calling the ActionForward from the servlet. I dont want to forward it from the
Action class. My servlet inherits ActionServlet. Iam doing ActionMapping mapping =
new mapping; mapping.findForward("test"); I have defined the uri test in my config
file. Please reply asap. Thanks

Re: How did i do that from within a servlet ??


Author: Kevin Cowan (http://www.jguru.com/guru/viewbio.jsp?EID=1224506),
Feb 1, 2005
If you don't want to use the ActionForward class you can use the response to
redirect...

response.sendRedirect(path);

hope this helps.

Does Struts work with a secure SSL connection?


Location: http://www.jguru.com/faq/view.jsp?EID=471962
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

Yes. Once SSL is installed for your container, the Struts custom tags and Action
Mappings will automatically insert the correct references so that all the page and
image links operate in SSL mode.

How do I install SSL for my container?


Location: http://www.jguru.com/faq/view.jsp?EID=471963
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

See:

• installing the Sun Secure Socket extension


• keytool
• and the documentation for your container.

Here are some common configuration mistakes:

• When installing standard extensions, install them under


$JAVAHOME\jre\lib\ext -- not under $JAVAHOME\lib\ext.
• If Struts links do not appear under SSL, see step 7 on the Secure Socket
Extension page.
• You may need to add
-Djava.protocol.handler.pkgs=com.sun.net.ssl.internal.www.protocol
to the command line which loads your container.
• If you have trouble importing your license key, be sure that your text file is
saved in standard UNIX file format

Here's a bird's eye overview

1. Install JSSE

2. Create a new keystore for certificate requests, using template that ships with Java

cp cacerts MY_SERVER.keystore

3. Change the default password

keytool -storepasswd -storepass changeit -new MY_KEYSTORE_PASSWORD -keystore


data.keystore

4. Generate a key, specifying an alias to use for this certificate

keytool -genkey -keyalg RSA -alias MY_SERVER_ALIAS -storepass


MY_KEYSTORE_PASSWORD -keystore data.keystore

Answer the questions, using your machine's fully-qualified name


(www.myserver.com) for "first and last name".

Use the same password for the key (using another password is not implemented).

5. Create a certificate request, based on the key created for the alias (step 2).

keytool -certreq -alias MY_SERVER_ALIAS -store pass MY_SERVER_PASSWORD


-keystore MY_SERVER.keystore

Capture the output to a text file (MY_SERVER.crs), being sure to keep a backup copy
in a safe place. This is your Certificate Request.

6. Generate a test certificate with Thawte, or another authority, to be sure


everything works, and import the certificate returned (MY_SERVER.crt) for this alias.
keytool -import -alias MY_SERVER_ALAIS -storepass MY_SERVER_PASSWORD
-keystore MY_SERVER.keystore -file MY_SERVER.crt

7. Repeat previous step to obtain a production certificate (unless you are self-signing
for intranet use). When you import the production certificate, it will replace the test
version.

How do I switch to SSL mode for logon, and then back again for the rest of
the session?
Location: http://www.jguru.com/faq/view.jsp?EID=471964
Created: Aug 8, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

This is still harder than it should be, but here's the drill:

The bad news is that you need to hardcode the schema to switch from standard to
SSL mode and back again. The good news is that you can mitigate the damage and
do most of it it all in the Struts-config.

<forward name="standard" redirect="true"


path="http://data.wxxi.org/wxxi-gavel/register/logon.jsp"/>
<forward name="secure" redirect="true"
path="https://data.wxxi.org/wxxi-gavel/register/logon.jsp"/>

which are called with code like this in the action

return mapping.findForward(secureMode ? "secure" : "standard");

where "secureMode" is tracked as a session attribute.

If they login or register in secure mode, you can end the process with a [[BIG
LINK]] that routes them back to the http scheme.

Messy, but it gets you through the day.

I haven't had time to think about it, but it seems to me that we should be able to
work this into the custom tags. Struts is very good about automagically converting
the links when you switch schemes, so it seems to me we should be able to force the
tags to one scheme or the other, when appropriate.

You could also calculate an absolute URL for this web app, based on things like
request.getServerName(), request.getContextPath(), and so on. So, another way to
do this would be to have an action that calculated the new absolute URL, wrapped it
in a new ActionForward with the "redirect" property set, and return that to the
controller servlet. It looks pretty much like what you quoted in the mail message.

NOTE: Because the controller servlet calls encodeRedirectURL() for you on


redirections, sessions should survive across this transfer whether or not you are
using cookies.
If you're running on ports other than the default (80 and 443), you will probably also
want a configuration parameter to define what the corresponding SSL and non-SSL
ports are.

Comments and alternative answers

Doesn't work with non standard ports


Author: Frank Russo (http://www.jguru.com/guru/viewbio.jsp?EID=541303), Dec 19,
2001

I tried this approach, and it works great when using the standard ports as you
mentioned. When I use other ports, the behavior is weird. When I switch back to http
mode, it still tries building part of the page (mainly the images) from the ssl port. You
mentioned using configuration parameters to define the non-ssl and ssl ports, but I'm
not sure how to do this. Is it in the struts-config? What would be the syntax for doing
that?

Thanks...

How to send POST data to an absolute URL?


Author: Dave Chang (http://www.jguru.com/guru/viewbio.jsp?EID=947974), Jul 12,
2002
Hi,
struts-config seems to restrict the path in <forward> to be relative URL if
redirect="false" is used. If an absolute URL is used, an error will occur. Question: If I
want to send POST data from a Form bean to an absolute URL via the ActionForward
mechanism of struts, how do I do that?
Thanks.
Dave Chang

Form validation errors in different frame? Possible? I'm writing my first


Struts application and want to use one frame containing the input form and
another frame to display the results.

If I use validation in the ActionForm (or populate ActionErrors in the Action


object), I know I can use <html:errors/> to display errors in the input form
(same frame).

But do I HAVE to display the errors in the same frame as the input form?
Could I do a <html:errors/> in the results frame and get them to display
there?

I can't use TARGET="resultsframe" because if an error occurs, the input


form will be displayed in the results frame. I'd need to refresh the results
frame from the input frame. But if the errors collection is only stored in the
request, it'd be too late to retrieve the errors I think.
Is there a solution? Can I get to the errors collection from a different frame
to the one containing the input form?

Thanks
Location: http://www.jguru.com/faq/view.jsp?EID=531007
Created: Oct 26, 2001
Author: Rob Breeds (http://www.jguru.com/guru/viewbio.jsp?EID=524998) Question
originally posed by Rob Breeds
(http://www.jguru.com/guru/viewbio.jsp?EID=524998

The only thing I came up with was to do the input validation using JavaScript and
dynamically set the TARGET if the validation succeeded.

I do have the error messages next to the corresponding input fields, but that only
works if the TARGET is set to the same frame as the input. If the input validates OK,
the response gets written to the input frame and not the results frame which is what
I want.

If no errors I could ALWAYS return the input frame and check a session attribute to
see if any results should be displayed, and if so change the results frame href so it
loads the results from session.

I think the only way to do this is turn form validation off and have any error
messages appear in the results frame. Not ideal, but it'll do for now!

Rob

Comments and alternative answers

struts errors
Author: Frank Bowar (http://www.jguru.com/guru/viewbio.jsp?EID=1085481), May
16, 2003
I ran into the same issue. I turned the auto validation off in struts-config and then in
my action did the following. ActionErrors errors = null; errors =
unitAddForm.validate(mapping, request); if((errors != null) && (errors.size() > 0))
{ session.setAttribute(Globals.ERROR_KEY, errors); . . forward to the appropriate
page/frameset } I believe the problem occurs because the errors are placed into the
request context, and when forwarding to a frameset, the request context is only valid
for the frameset and none of the frames. It would be nice if struts would put the errors
into the context based upon the scope of the associated action.

Re: struts errors


Author: daniel carter (http://www.jguru.com/guru/viewbio.jsp?EID=1137803), Jan
8, 2004
if you put the errors into the session, then they will appear on all forms as struts
never clears them from the session, even when doing subsequent validations.
Better to put them into the request i found.
Page caching by overriding the getOutputStream() and getWriter()
methods. Reading this( see second answer)
I wonder how I can do this in
struts. I want to save the response
to my own stream so I can save it.
Which class do I extend in strus do
get this to work?
Location: http://www.jguru.com/faq/view.jsp?EID=531024
Created: Oct 26, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by raffe paffe (http://www.jguru.com/guru/viewbio.jsp?EID=28822

In your Action, you can just return null instead of an ActionForward

public ActionForward perform(ActionMapping mapping,


ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
response.setContentType("text/plain");
response.getWriter().print("Hello World");
return (null);
};

HTH -Ted

war file and directories structure for struts applications Could someone give
me a sample structure of a simple application (2 or 3 jsp, 2 or 3 Action
classes ...) including:

• the appropriate directories structure for the jsp, sources files and
.class files, libs, and build.xml,web.xml, struts-config.xml etc...
• the corresponding "build.xml" file WITH the correct WAR tag in order
to generate the proper .war file to be deployed into some servlet
container like Tomcat.

All the sample "build.xml" struts applications i've found don't indeed show
how to write this war tag
Thanks,
Location: http://www.jguru.com/faq/view.jsp?EID=531027
Created: Oct 26, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by Oops PRz (http://www.jguru.com/guru/viewbio.jsp?EID=527561

In open source arenas, it's become a popular practice to put the source below WEB-
INF/src/java but that's a matter of preference. Most people tend to keep the
build.xml under WEB-INF where it's easy to find.

The build.xml was written with that assumption, but you could change it to run from
or get the source from anywhere you like.
Likewise, where you put (or name) the struts-config.xml " and the tld's can be
configured in the web.xml, and is also a matter a preference.

The ApplicationResource.properties file has to be on the classpath, and since classes


is always on the classpath putting it there makes it easy for the container to find.

Putting the JSPs below WEB-INF can provide an extra layer of security, but can also
make it harder to reference stylesheets and the like.

HTH - Ted.

Comments and alternative answers

Here's a simple directory structure that worked for me...


Author: John Munsch (http://www.jguru.com/guru/viewbio.jsp?EID=236478), Dec
16, 2002
base directory/ (this is the name of your war file)
JSP files
image files
HTML files
CSS files
any subdirectories containing additional JSP, HTML, images, and
CSS
WEB-INF/
struts-config.xml
web.xml
TLD files for various tag libraries
lib/ (various .jar files for libraries you used)
classes/ (compiled .class files for your actions and action
forms)
META-INF/ (this is part of the .war file)
MANIFEST.MF (the manifest file from the .war file)

Underneath the classes directory you would have compiled code for forms and
actions. For example:

com/
johnmunsch/
strutstest/
actions/
LoginAction.class
SearchAction.class
forms/
LoginForm.class
SearchForm.class

Indexed Properties

Can we access members of an array like <form:select property="array[i]">


in a for loop... It works if I use constants but not expressions..
property="array[0]" is fine but not array[i] or array[<%=i>] for the
property attribute of form:select. Any clues???

Location: http://www.jguru.com/faq/view.jsp?EID=531742
Created: Oct 27, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

The property accessor syntax in Struts 1.0 supports only constants as array
subscripts.

You might consider using some sort of runtime expression instead, to dynamically
calculate the property to be retrieved. Assume that "i" is an integer variable, and you
are inside a loop:

<form:select property='<%= "array[" + i + "]" %>'/>

In the Struts nightly build, indexed properties are supported directly, so that
scriptlets like this are not needed

Comments and alternative answers

error in submission
Author: Susan Cai (http://www.jguru.com/guru/viewbio.jsp?EID=1107860), Aug 11,
2003
When user click "submit", form reset will be called, and get a empty array. How to
settle this problem?

Re: error in submission


Author: Ritu kumar (http://www.jguru.com/guru/viewbio.jsp?EID=314981), Sep
26, 2003
The problem I am having is that when I submit this form the form validation is not
being called and the form fields are not being set

Has anyone had luck using radio buttons?

Location: http://www.jguru.com/faq/view.jsp?EID=531746
Created: Oct 27, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

The idea behind a radio button is that you have a String field that has one of a fixed
set of values, and you want to render one radio button for each of them.

Let's assume that your bean property "gender" can have property values "Male" or
"Female". You might display them like this:

<html:radio property="gender" value="Male">


<bean:message key="gender.male"/>

</html:radio>

<html:radio property="gender" value="Female">

<bean:message key="gender.female"/>

</html:radio>

A particular radio button will be selected if the value returned for this property
matches the "value" attribute of that button's <html:radio> element.

In the example above, we're also looking up the actual text of the strings displayed
on the HTML page in a message resources bundle, so that it is suitably
internationalized.

[Craig McClanahan]

Comments and alternative answers

"Grouping of radio buttons in struts framework"


Author: V.V.Narasimha Raju S.R.K.
(http://www.jguru.com/guru/viewbio.jsp?EID=985024), Aug 19, 2002

Hi,

This answer is informative but I want to know "Grouping of radio buttons in struts
framework" for example: I want to display the user information with Status field
('Active' and 'InActive') for N number of users with radio buttons. How can i handle
this situation. Right now I am unable to select the status of individual user, because it
is taking all radio buttons as one control.

thanks in advance.
Raju.

Radio buttons are grouped by name.


Author: Artur de Sousa Rocha
(http://www.jguru.com/guru/viewbio.jsp?EID=70489), Jan 10, 2003
Radio buttons are grouped by their names, so if you need separate radio button
group for each user, they must have the same name for a single user, but different
for different users. For example: "user" + userID. Thus, if you display users
with IDs 3, 5, and 11, you will have:
<input type="radio" name="user3" value="Active">
<input type="radio" name="user3" value="InActive">

<input type="radio" name="user5" value="Active">


<input type="radio" name="user5" value="InActive">

<input type="radio" name="user11" value="Active">


<input type="radio" name="user11" value="InActive">
Unfortunately, as of Struts 1.0.2 you will have to handle this naming scheme
"manually".

Re: Radio buttons are grouped by name.


Author: h p (http://www.jguru.com/guru/viewbio.jsp?EID=1094323), Jul 10,
2003
your answer was really helpfull but where do you give the name to the Radio
Button. Suppose I am dynamically generating Radio Buttons so where in the
<html:radio> should I specify the name of the button so that it each are
identified.
could you please write the above code using struts tags. Thank you very much
in advance.

Re[2]: Radio buttons are grouped by name.


Author: Niraj Jain
(http://www.jguru.com/guru/viewbio.jsp?EID=1262136), Sep 13, 2005
you want to set the radio button for each individual user and want to
generate the user name dynamically. you can try i did it long time back
<%int i=0;%> <% while(i!=10){%>
"user<%=i%>" <input type="radio" name="user<%=i%>"
value="Active"> "user<%=i%>" <input type="radio"
name="user<%=i%>" value="InActive"> <% i++;}%>

ActionErrors,ActionError about display the error message. In the strut


example, we should new ActionError("error.password.mismatch")
"error.password.mismatch" define in the config file, if the property does not
exit, then I can see nothing in the browser , I wanna to know whether I can
display the property name even I does not define the property. thanks
Location: http://www.jguru.com/faq/view.jsp?EID=531811
Created: Oct 27, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by Yang Liu (http://www.jguru.com/guru/viewbio.jsp?EID=527494

Actually, there is an ActionServlet property that governs this. In your web.xml,


include this:

<init-param>
<param-name>null</param-name>
<param-value>false</param-value>
</init-param>
with the other settings for your ActionServlet.

See the Struts Javadoc for other ActionServlet settings

HTH - Ted

Comments and alternative answers

Struts 1.1 addition


Author: scott carlson (http://www.jguru.com/guru/viewbio.jsp?EID=428708), Jun 20,
2002
And in Struts 1.1, you can add a null="false" to your <message-resources > tag in
your struts-config.xml . For example :

<message-resources parameter="ApplicationResources"
key="org.apache.struts.action.MESSAGE" null="false" />

Should we be chaining action servlets?

We're putting together a series of screens where we would say... logon (to
main menu), list parties (to list result screen), then add party (to party
detail screen), submit add (back to list result screen).

The notion of actions makes perfect sense to perform the business logic as a
result of the various submits. However, we're currently questioning the use
of actions in setting up the resultant page.

It appears that the actions themselves are logically dependant on the page
(JSP) about to be rendered. As a side; surely this degrades application
maintainability somewhat because it reduces the ease at which page flow
can be altered, i.e simply by changing struts-config.xml

In the case above, our 'submit add' needs to perform a list again in
preparation for the redisplay of the result screen.

Would we be correct in splitting this functionality between multiple action


classes and chaining them. I've seen on the forum somewhere this idea
refered to as 'the path to madness'!

Otherwise, in the case above, should we simply not return post-add to the
list result screen, or is there (or should there be) in struts a mechanism for
pre-processing a particular page, i.e. not leaving it all up to action objects?
Have I missed a third/forth option that would decouple actions in some
way?

Eagerly awaiting any feedback.

Steve Crowe.
Location: http://www.jguru.com/faq/view.jsp?EID=533532
Created: Oct 30, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by steven crowe
(http://www.jguru.com/guru/viewbio.jsp?EID=530233

An Action is intended as an adapter between the HTTP layer and the rest of your
application. Generally, the rest of your application should be represented by business
objects that have no dependancies on HTTP or Struts.

So, the business logic should not be *in* the Action, but something that the Action
*calls*.

This makes it easier for Actions to handle more than one task. Since the logic is
encapsulated elsewhere, each task is simpy a method call.

This also makes it easier for logic to be accessed by more than one Action (or from
more than one application).

In this case, there could be a business method for the listResult page, that an Action
could call before forwarding to that page.

If the correct prerequesites are still in the request, simply forwarding to another
Action can also be a clean solution, so long as this is documented in the struts-
config.

Where it gets iffy is when people start building dynamic query strings so they can call
another Action. This is a retreat to Model 1, and smells like a kludge, since it implies
that the business logic is not available outside the Action, where it could be cleanly
called with a method (rather than a query string).

For an example of using business objects with Struts, see the early release of
Artimus at http://husted.com/struts/resources.htm#new.

HTH -Ted

Comments and alternative answers

Similar problem chaining actions


Author: Ken Bernstein (http://www.jguru.com/guru/viewbio.jsp?EID=1233524), Mar
18, 2005
Hi,

I am running into a similar issue, except with a twist. I want to chain actions together,
however the ActionForm gets reset between the 2 actions. So, I am setting some fields
in the ActionForm in the first action, but by the time the second action (the one that
implements the the "presentation logic" (populating dropdowns, setting defaults, etc.)
gets invoked, all the fields in the form are gone.

The only solution I can think of is to use request.setAttributes, however it seems


wasteful to have to copy the attributes of the request into the form.

Any help would be appreciated, Ken

Struts post-1.0 and Tomcat 3.2.x My post-1.0 version of Struts crashes on


tomcat 3.2.x. What can I do about this?
Location: http://www.jguru.com/faq/view.jsp?EID=533533
Created: Oct 30, 2001
Author: Tom Klaasen (http://www.jguru.com/guru/viewbio.jsp?EID=532427)
Question originally posed by Tom Klaasen
(http://www.jguru.com/guru/viewbio.jsp?EID=532427

Put xerces.jar in your TOMCAT_HOME/lib directory, and rename the files parser.jar
and jaxp.jar in that same directory to zparser.jar and zjaxp.jar, respectively.

Multiple button support How should multiple button support be handled in


Struts? Each button gets submitted with different text, but in order to
separate the view from the controller that text should not appear in the
Action. I'm curious how others have dealt with this situation.
Location: http://www.jguru.com/faq/view.jsp?EID=543699
Created: Nov 9, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by Erik Hatcher PREMIUM
(http://www.jguru.com/guru/viewbio.jsp?EID=405274

Without Javascript, I don't think there is another solution, since that is all the
information that HTTP provides.

With Javascript, you can have the button set a hidden property on the form, and
then key on that.

This example uses the property "forward", which could also be a property on the
ActionForm.

<html:hidden property="forward" value="error"/>


<html:submit onclick="set('update');">UPDATE</html:submit>
<html:submit onclick="set('copy');">COPY</html:submit>
<html:cancel onclick="set('cancel');">CANCEL</html:cancel>

function set(target) {
document.forms[0].forward.value=target;
};

A good trick here is to use a generic "routing" or "relay" action, so you don't have to
hardcode some type of switch into the Action. It's just one line in the perform
method:
return mapping.findForward(request.getParameter("forward"));

This can be used any number of times in a Struts application, just by changing the
form bean and the local forwards in its mapping.

<action
path="/prospect/Submit"
type="org.apache.scaffold.http.RelayAction"
name="prospectForm"
scope="request"
validate="false">
<forward
name="update"
path="/do/prospect/Store"/>
<forward
name="cancel"
path="/do/prospect/Current"/>

HTH - Ted

Comments and alternative answers

Additional alternatives
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042), Jan 8,
2002

There is now a new standard Action in the nightly build, that is useful for calling
different Actions from the same form. See
org.apache.struts.actions.LookupDispatchAction in the nightly build.

Also in the contrib folder of the nightly build, there is a package called "scaffold"
with another standard Action, org.apache.scaffold.http.FindForwardAction (my
personal favorite).

-Ted

Multiple submit buttons


Author: Greg Hess (http://www.jguru.com/guru/viewbio.jsp?EID=733724), Jan 24,
2002
Without Javascript I have been able to support multiple submit buttons on the same
form by setting the property of the submit tag. <html:submit property="add"
value="Add"/> <html:submit property="edit" value="Edit"/> Add these new
properties to your ActionForm and in the Action class you can determine what button
has been clicked by evaluating if(getAdd()== null).

Re: Multiple submit buttons


Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042), Jan
24, 2002

Yes, but what you are really doing is keying on the value of the buttons label. This
is fine for single language applications, but the other solutions would also work in
an internationalized application.

-Ted

Re[2]: Multiple submit buttons


Author: Greg Hess (http://www.jguru.com/guru/viewbio.jsp?EID=733724),
Jan 25, 2002
Sorry, I didnt actually provide my internationalized code for simplicity.
<html:submit property="add"> <bean:message key="page.form.add.label"/>
</html:submit> In my code I am not using the value of the property rather just
the (propery != null). Is this considered bad form or unreliable? I know this is
not possible with all html inputs like text inputs as the value is always inserted
into the http request. But with radio buttons, check boxes and the submit the
key value pair will only be placed into the request if it is selected or clicked so
I have found it nessessary at times to evaluate the (!= null). I am also restricted
by the fact that I can't use JavaScript. Thanks for your prompt response.

Re[3]: Multiple submit buttons


Author: Emre Akbas
(http://www.jguru.com/guru/viewbio.jsp?EID=1247327), Jun 6, 2005

Ted (the contributor of LookUpDispatchAction to Struts) may have


forgotten to answer your question. Here is my experience:

When you implement multiple buttons as you described above, you should
reset the actionform on each submit if you want to stay at the same page.
An example for "staying at the same page" is a form that couldn't pass
validation. When a field of a submitted form is not valid, you should print
all of the form, with its content of course, to the client who has just filled
the form, and this unfortunately means previously-pressed-button
information would persist. To prevent this, you can reset the actionform,
but then the info filled-in by the client would be lost, which is of course an
undesired situation.

In short, using LookUpDispatchAction is the best way.

Re: Multiple submit buttons


Author: Richard Wan (http://www.jguru.com/guru/viewbio.jsp?EID=953512), Jul
17, 2002
A similar solution would be to implement the form bean as follows:
public void setAdd(String) {setForward("add");}
public void setEdit(String) {setForard("edit");}

and then as the final line in the Action:

return mapping.findForward(formBean.getForward());

Re[2]: Multiple submit buttons


Author: shibani belsare
(http://www.jguru.com/guru/viewbio.jsp?EID=1221086), Feb 3, 2005
could me send the sample code you have done here?

Non JavaScript Alternative?


Author: Pieter Hertogh (http://www.jguru.com/guru/viewbio.jsp?EID=782813), Mar
5, 2002
If you name your property tags different you can distinguish the button pressed form
the http request.
Just get the parameter named submit.* and retrieve the * to get the button pressed.

Should work fine i think.

<html:submit property="submit.update" value="Update document">


<html:submit property="submit.delete" value="Remove document">

Re: Non JavaScript Alternative?


Author: Rod Madden (http://www.jguru.com/guru/viewbio.jsp?EID=1139442),
Feb 16, 2004
Can you show me an example of what the ActionForm would look like for this ?

Don't forget about the property parameter.


Author: Artur de Sousa Rocha (http://www.jguru.com/guru/viewbio.jsp?EID=70489),
Dec 20, 2002
The <html:submit> tag has a property parameter. You can "attach" each of the submit
buttons to a different property. Then, after submitting only one of these properties will
be non-null. You can use this information to find out the user's choice.

Re: Don't forget about the property parameter.


Author: TirumalaRao Chamalla
(http://www.jguru.com/guru/viewbio.jsp?EID=1077243), Apr 17, 2003
The best way to do it is using LookUpDispatchAction class which is a new feature
in the ver 1.1, U have to override the getKeyMethodMap()(may not be the xact
syntax). put the key here in the HashMap and and method name as the value
return the hashmap. in the <html:submit property="action"><bean:message
key"somekey.mykey">, the key should b there in the Properties file, and in the
StrutsConfig.xml file <action mapping> we have to set the <parameter='action'>...
THis works fine I want to implement the same on click of an image instead of the
submit button can any one help me in this regard

Re[2]: Don't forget about the property parameter.


Author: Narendhran Kannappan
(http://www.jguru.com/guru/viewbio.jsp?EID=1112079), Sep 1, 2003
could u send me the code for this one...

LookUpDispatchAction limitation ...


Author: prashant jani (http://www.jguru.com/guru/viewbio.jsp?EID=100991), Sep 17,
2003
Hi,

There are a few limitations. Consider the following:


in the jsp, the <html:form ...> needs an action form to be defined.
what if i dont have an action form for the action mapping.
this is more of struts limitation towards form submission.

-----------------struts-config.xml--------------

<!-- Test Action -->


<action path="/testLookupAction"
type="org.apache.struts.webapp.validator.AppLookupDispatc
hAction"
scope="request"
parameter="submit">
<forward name="success" path="/index.jsp"/>
</action>

This action does not have a form mapping.


The basic purpose of the action is to differentially fwd the request
using the Action class methods.
i am assuming the parameter plays a role in getting the parameter just
like the DispatchAction.

-------- jsp page ---------------------------------------

<form action="/validator/testLookupAction.do">
<html:submit property="submit">
<bean:message key="action.add"/>
</html:submit>
<html:submit property="submit">
<bean:message key="action.delete"/>
</html:submit>
<html:submit property="submit">
<bean:message key="action.edit"/>
</html:submit>
</form>

---------- .properties file --------------


action.add=executeAdd
action.delete=executeDelete
action.edit=executeEdit

---------------AppLookupDispatchAction.java--------------
protected Map getKeyMethodMap() {
Map map = new HashMap();
map.put("action.add", "executeAdd");
map.put("action.delete", "executeDelete");
map.put("action.edit", "executeEdit");

System.out.println("getKeyMethodMap");
return map;
}
public ActionForward execute

-------
other business methods
public ActionForward executeAdd ....
....

=========
however when i run the following:
http://localhost:8080/validator/testLookupAction.do?submit=executeDelete

the execute method is called. the getKeyMethodMap is never executed ...

can u help me on this. i cannot figure where the problem is.

regards
Jani

Re: LookUpDispatchAction limitation ...


Author: Tim Meredith (http://www.jguru.com/guru/viewbio.jsp?EID=1159135),
Mar 31, 2004
You are overriding the execute() therefore the getKeyMethodMap() is not called
to use your methods. Remove the execute() method from your action
(AppLookupDispatchAction in this case)

Re[2]: LookUpDispatchAction limitation ...


Author: charles rad (http://www.jguru.com/guru/viewbio.jsp?EID=1242325),
May 12, 2005
This is true. However, and I can't seem to get past this, when you simply click
on the enter button , and specially if you have a text field with a value in it,
then program doesn't know what to do. any thoughts?

Multiple form beans per Action class Can I have multiple form beans per
action class? If YES how would the struts config file look like?
Location: http://www.jguru.com/faq/view.jsp?EID=543700
Created: Nov 9, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by Ranjiith Selvarjan
(http://www.jguru.com/guru/viewbio.jsp?EID=421879
Not as such. The Action.perform() method only takes a single form bean as a
parameter.

You can nest beans. See the Bean Developers guide for details, and Struts-simple for
an example.

Of course, you can always create and populate whatever other beans you need in the
Action. Typically, the ActionForm is just used to get the data into the Action, and then
it is transferred to more capable beans, with typed data.

HTH - Ted

Comments and alternative answers

It is possible by extendig ActionServlet


Author: frank prumbaum (http://www.jguru.com/guru/viewbio.jsp?EID=578394),
Dec 10, 2001
You can do so by extending ActionServlet to implement this new behavior. We have
done this by overriding processActionForm to just get the name of the bean to fill
from an input type=hidden name=serviceName parameter from the request. All what's
left to be done is declaring these beans in the form-beans section of struts-config and
providing a forward-mapping for the action. You can then link many forms with each
different beans to one action-class

Here our implementation of processActionForm which uses Beans of type


serviceName+"Form" and names (what you put in form-tags)
serviceName+"bean"
<xmp>
protected ActionForm processActionForm(ActionMapping mapping,
HttpServletRequest request)
{
HttpSession session = request.getSession();
// Is there a form bean associated with this mapping?
String formBeanName = mapping.getAttribute();
if (formBeanName == null || formBeanName.equals("nullbean"))
{
formBeanName =
request.getParameter("serviceName")+"bean";
if(formBeanName==null) {
return null;
}
}

// Look up the existing form bean, if any


if (debug >= 1)
log(" Looking for ActionForm bean under attribute '" +
formBeanName + "'");
ActionForm instance = null;
if ("request".equals(mapping.getScope())) {
instance = (ActionForm)
request.getAttribute(formBeanName);
} else {
instance = (ActionForm)
session.getAttribute(formBeanName);
}

// Bestimmung der erwarteten Formbeanklasse;


// wenn das mapping keinen Namen führt, dann nehme den Namen
der Form
String name = mapping.getName();
if(name==null) {
name=formBeanName;
}
String className = null;
ActionFormBean formBean = findFormBean(name);
if (formBean != null)
className = formBean.getType();
else
return (null);

// Can we recycle the existing form bean instance?


if ((instance != null) &&
className.equals(instance.getClass().getName())) {
if (debug >= 1)
log(" Recycling existing ActionForm bean instance of
class '"
+ className + "'");
return (instance);
}

// Create a new form bean if we need to


if (debug >= 1)
log(" Creating new ActionForm instance of class '"
+ className + "'");
try {
instance = null;
Class clazz = Class.forName(className);
instance = (ActionForm) clazz.newInstance();
} catch (Throwable t) {
log("Error creating ActionForm instance of class '" +
className + "'", t);
}
if (instance == null)
return (null);

// Store the newly created bean in the appropriate scope


if (debug >= 1)
log(" Storing instance under attribute '" + formBeanName
+ "' in scope '" + mapping.getScope() + "'");
if ("request".equals(mapping.getScope()))
request.setAttribute(formBeanName, instance);
else
session.setAttribute(formBeanName, instance);
return (instance);

}
</xmp>

Re: It is possible by extendig ActionServlet


Author: Pawan Kumar Shrivastava
(http://www.jguru.com/guru/viewbio.jsp?EID=1162795), Apr 14, 2004
I think with DispatchAction also we can do the same. In struts-config.xml we can
have our Multiple Action Mappings which will point to same Action Class but
will be having different Form Beans associated with it. And we can specify the
function to call in parameter in struts-config.xml. So for every form bean
argument in method of Action Class we can cast it to appropriate form beans.

Re[2]: It is possible by extendig ActionServlet


Author: Adam Strickland
(http://www.jguru.com/guru/viewbio.jsp?EID=1162842), Apr 14, 2004
Pawan-
Could you provide a sample struts-config.xml illustrating what you mean?
Perhaps it's container-specific, but I'm running into a problem where, if the
name attribute of the action tag for a given subclass of DispatchAction isn't
supplied in the struts-config.xml, then the form parameter inside the
method is null. This is causing a problem as I would like to use a variety of
forms to be processed by the same DispatchAction subclass.

In case it is container-specific, I'm using JBoss 3.2.1 with Tomcat 4.1.24


embedded.

problem in validation by client side javascript generated from


validation.xml file in struts.
Author: hemali petare
(http://www.jguru.com/guru/viewbio.jsp?EID=1177749), Jun 22, 2004
I have two forms on one jsp pages both forms are having two input fields
and one submit button. I am not able to invoke respective javascript on
submit event. although javascripts functions are avalilable on that page. it
works for one form's validation. not for both.

Re: problem in validation by client side javascript generated from


validation.xml file in struts.
Author: hans guberg
(http://www.jguru.com/guru/viewbio.jsp?EID=1190189), Aug 3, 2004
Hi i have this exact same problem... has anyone got a solution to this?

Re[2]: problem in validation by client side javascript generated


from validation.xml file in struts.
Author: ahmet mutlu
(http://www.jguru.com/guru/viewbio.jsp?EID=1250927), Jun 29,
2005
struts generates , required javascript class for each form, however,
with same name. if you have multiple forms, then you have multiple
requred class,like: <script> function required () { ..... } </script>
<script> function required () { ..... } </script> when validation is
invoked, it goes insane. i handled validation manually for 2nd form.

Re[2]: It is possible by extendig ActionServlet


Author: Madhu Raj Soudathikar
(http://www.jguru.com/guru/viewbio.jsp?EID=1235385), Mar 29, 2005
In the case of DispatchAction, We can have more than one form per action
class but for a Single request/parameter in case of dispatchAction, there exists
only one form bean. If i want to use more than one form beanfor each submit/
request, how should i go about it?

Re: It is possible by extendig ActionServlet


Author: Lennarth Anaya (http://www.jguru.com/guru/viewbio.jsp?EID=1189596),
Jul 30, 2004
I'm trying to do some thing like your example. In my case, if current FormBean
isn't in session scope, I must create the corresponding Transfer Objects in a nested
hirearchy collection. I don't want to parse struts-config.xml. How do you
implement your findFormBean() method ?

Re[2]: It is possible by extendig ActionServlet


Author: Lennarth Anaya
(http://www.jguru.com/guru/viewbio.jsp?EID=1189596), Jul 30, 2004
I got it, I found the findFormBeanConfig() method provide by Struts
ApplicationConfig. Thanks for bounch of answers...

Re[3]: It is possible by extendig ActionServlet


Author: Fahad Khan
(http://www.jguru.com/guru/viewbio.jsp?EID=1226900), Feb 13, 2005

Would you kindly elaborate a little on how did you find ApplicationConfig
useful in your particular situation?

I'd appreciate if you describe the proceedure that made possible to use
single action class for multiple forms.

Thanks,

Fahad.

Re[4]: It is possible by extendig ActionServlet and RequestProcessor


Author: Prashanth Veldhi (http://www.jguru.com/guru/viewbio.jsp?EID=1245874), May 26
2005
Consider a example where you have
one action class TestAction,
two form beans TestForm and TestForm1
two JSP's test.jsp and test1.jsp.
test1.jsp uses TestForm1 and test.jsp uses TestForm. Both the JSP's fire action to Single
Action Class TestAction. The Action class has to get the appropriate form bean.
Solution:
As per the struts framework 1.1 you can do it by overriding ActionServlet and
RequestProcessor class as follows
public class MyRequestProcessor extends RequestProcessor
{
protected ActionMapping processMapping(HttpServletRequest request,
HttpServletResponse response, String path)
throws IOException
{
System.out.println("ProcessMapping of
MyRequestProcessor called...");
ActionMapping mapping =
(ActionMapping)moduleConfig.findActionConfig(path);

if(mapping != null)
{

request.setAttribute("org.apache.struts.action.mapping.instance", mapping
System.out.println("Set The Form bean from the
request...if available");
String myBean =
request.getParameter("myBean")==null?"":request.getParameter("myBean");
System.out.println("Bean You Mentioned..." +
myBean);
if(myBean != "")
{
System.out.println("Bean metioned earlier
is..." + mapping.getName());

mapping.setName(myBean);

System.out.println("After setting the


bean..." + mapping.getName());
}
return mapping;
}
ActionConfig configs[] =
moduleConfig.findActionConfigs();
for(int i = 0; i < configs.length; i++)
if(configs[i].getUnknown())
{
mapping = (ActionMapping)configs[i];

request.setAttribute("org.apache.struts.action.mapping.instance", mapping
return mapping;
}

response.sendError(400,
getInternal().getMessage("processInvalid", path));
return null;
}

get the hidden parameter (myBean) value from the jsp page with the form bean value and s
the particular form bean.
public class MyActionServlet extends ActionServlet
{
public void init()
throws ServletException
{
System.out.println("Init Method Called....");
initInternal();
initOther();
initServlet();

getServletContext().setAttribute("org.apache.struts.action.ACTION_SERVLET
this);
ModuleConfig moduleConfig = initModuleConfig("", config);
initModuleMessageResources(moduleConfig);
initModuleDataSources(moduleConfig);
initModulePlugIns(moduleConfig);
//moduleConfig.freeze();
for(Enumeration names =
getServletConfig().getInitParameterNames(); names.hasMoreElements();)
{
String name = (String)names.nextElement();
if(name.startsWith("config/"))
{
String prefix = name.substring(6);
moduleConfig = initModuleConfig(prefix,
getServletConfig().getInitParameter(name));
initModuleMessageResources(moduleConfig);
initModuleDataSources(moduleConfig);
initModulePlugIns(moduleConfig);
//moduleConfig.freeze();
}
}
destroyConfigDigester();
}

Look at the lines commented...this allows to create the Form bean.


Jsp pages
test1.jsp
<%@ taglib uri="struts/html" prefix="html"%>
<html>
<html:form action="\test.do" name="testForm1"
type="com.cognizant.form.TestForm1">
Name: <html:text property="name" />
Age: <html:text property="age" />
Country: <html:text property="country" /><html:submit/>
<input type="hidden" name="myBean" value="testForm1">
</html:form>
</html>

the hidden form field myBean takes the appropriate form bean name. In this case it is
testForm1.
test.jsp has testForm as hidden field value...
Make changes To Struts-config file with
<controller processorClass="com.cognizant.processor.MyRequestProcessor" /
Your WEB.XML should look like this
<servlet-name>action</servlet-name>
<servlet-class>com.cognizant.servlet.MyActionServlet</servlet-class>

Re[5]: It is possible by extendig ActionServlet and


RequestProcessor
Author: william edwards
(http://www.jguru.com/guru/viewbio.jsp?EID=1245886), May 26,
2005
Just one question, what do I write in the //moduleConfig.freeze();
bit - what should it look like?

Re[5]: It is possible by extendig ActionServlet and


RequestProcessor
Author: william edwards
(http://www.jguru.com/guru/viewbio.jsp?EID=1245886), May 26,
2005
The "MyRequestProcessor" also clashes with the tiles request
processor in my struts-config. An error occurs when loading up
because tiles says "MyRequestProcessor" is incopatable with its
TilesRequestProcessor.

Re[6]: It is possible by extendig ActionServlet and


RequestProcessor
Author: william edwards
(http://www.jguru.com/guru/viewbio.jsp?EID=1245886), May
26, 2005
I found the solution to this problem. The "MyRequestProcessor"
must subclass the TilesRequestProcessor instead of the normal
RequestProcessor.

Re[6]: It is possible by extendig ActionServlet and


RequestProcessor
Author: Prashanth Veldhi
(http://www.jguru.com/guru/viewbio.jsp?EID=1245874), May
26, 2005
Nothing required...for that bit. Remove the commented code.

For tilesrequestprocessor... MyRequestProcessor has to extend


the related tiles RequestProcessor class and override the
appropriate method.

At present MyRequestProcessor extends


org.apache.struts.action.RequestProcessor

Reason:
When you look at ActionServlet init() method, it calls
moduleConfig.freeze() method

when you call mapping.setName("formbean")in


RequestProcessor's processMapping method ,it inturn calls
freeze() method of ApplicationConfig class.

There is a boolean variable called "configured" in the above


class which is initialized as false.

The variable is set to true when freeze method is called.


So, when ever you call mapping.setName() the method checks
for "configure" variable and if it is true, the method throws
IllegalStateException and does not allow to set our form bean.

Re[5]: It is possible by extendig ActionServlet and


RequestProcessor
Author: atul jain
(http://www.jguru.com/guru/viewbio.jsp?EID=1255962), Aug 4,
2005
it is not possible extending actionservlet but possible extending
requestprosser class

Dynamic Form Elements

I posted this earlier but I received no comments on specific current


solutions that will address this problem. I was also wondering if the nightly
build has the following ability within it.

Let me give an idea of what I am trying to accomplish and then see if you
can feedback.

Using struts (obviously) I am creating a reusable contact form. It is


configured through an xml-config file that defines where the contact form
goes and the smtp server it is to use, etc.. I want to set it up so that it does
not have to be recompiled upon alternate use. This is one part of a set of
components that make it easy for web designers to add functionality to
websites they are building using the struts framework (whether they know
it or not). i.e. most web designers to not have ide for compiling java classes.
So, with those design goals in mind let me share with you my issue.

The contact form by default captures the Name, Address, City, State, Phone
Number, and any other basic contact form info needed. It has an
ActionForm bean that captures the input of these predefined items and the
data is then passed on to the Action and sent as an email to the recipient.
My hangup is... I need to allow the flexibility of adding form elements to the
form that are not defined in the ActionForm bean. I would also need to be
able to pass the values back to the form in the event that a validation error
occurs with the form. With the model the way it is I would have to
specifically define the setters and getters in the ActionForm so that the
Action could retrive the values of each form element and use them or route
them back to the input form for errors or to another Action.

Is there a way to have a generic getter/setter that can capture any non
defined data? For example say a company cleans linen and they want to add
a form element that asks for the type of detergent the contactee prefers.
The added form element is called "preferredDetergent" yet it is not
specifically defined in my ActionForm bean. First, how would I avoid getting
an error that says preferredDetergent is not defined in xxxForm? Next, how
would I then capture that value in the ActionForm for use in error checking
and/or usage in the Action class?

Brandon Goodin
Phase Communications
P (406)862-2245
F (406)862-0354
http://www.phase.ws

Location: http://www.jguru.com/faq/view.jsp?EID=543702
Created: Nov 9, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by Brandon Goodin
(http://www.jguru.com/guru/viewbio.jsp?EID=542437

The ActionForms extend the html:form tags so that they can be populated, and
repopulated, from the request.

The ActionForm properties and the tags are tightly coupled, and neither are designed
to be used dynamically.

Of course, not every property has to be populated. So there could be the old trick of
adding several "UserDefined" properties to form. In the JSP, the properties might be
labled user1, user2, et cetera, but the external user labels could be anything at all.

Using the validator form, error checking can be performed by updating the
validate.xml and Application resources and restarting the application.
In the Action itself, you would need to add some type of handler to check if the user
defined fields were not null. To label them in your email message, you could do some
type of "reverse lookup" on the application resources, to get the field labels from the
validation messages.

HTH - Ted

Comments and alternative answers

ActionForm to handle dynamically generated fields


Author: Chan Mike (http://www.jguru.com/guru/viewbio.jsp?EID=1032363), Nov 30,
2002
I'm working on an application which need to render html objects
dynamic

The objects to render will depend on data read from database table
prior to construction (by action method) of jsp form.

In my jsp form, each row from db table will rendered as a table row.
However there is no way to determine the no of rows in advance. Also,
in each row, there will be a status colomn which in turn decide
whether a checkbox will be rendered in each row.

Thus, I cannot pre-assign fields in the ActionForm as what is


rendered by jsp is completely unpredictable.

Right now, i am completating on creating a 'collection' variable


inside the jsp. This variable will have to updated whenever any of
checkboxes is selected. On the ActionForm, i will predefined the same
collection variable.
Would welcome any1 with experience in this area.

Re: ActionForm to handle dynamically generated fields


Author: neal ravindran (http://www.jguru.com/guru/viewbio.jsp?EID=17737),
Dec 5, 2002
I am in a similar situation. Were you able to find a solution to this dilemma?

Re[2]: ActionForm to handle dynamically generated fields


Author: Oswin Ondarza
(http://www.jguru.com/guru/viewbio.jsp?EID=1057273), Feb 16, 2003
in struts 1.1 you can use DynaActionForm.

please refer to this link:

http://www.onjava.com/pub/a/onjava/2002/10/30/jakarta.html?page=last

Re[3]: ActionForm to handle dynamically generated fields


Author: Glen Whitbeck
(http://www.jguru.com/guru/viewbio.jsp?EID=1060827), Feb 26, 2003
The above referenced link discusses the use of DynaActionForm. While
the DynaActionForm appears to help by allowing attributes to be defined
in an xml file (instead of on a Java object - forcing an application restart
after any change), it still seems to fall short by forcing three duplicate
definitions (once on the page, once in the xml file, and once in the
(String)form.get("mySpecialHardCodedPropertyName") code on the
ultimate business/service object). Which, by the way, still appears to cause
an application restart since the ulimate business/service object will have to
change what it uses in the __form.get("xxx") code.

If I do not use Struts, my servlet can simply construct a generic Hashtable


that is populated with everything in the request and pass it to the service
layer.

Then, my service layer can instantiate the appropriate business/service


object (based on the requested service) and populate it using reflection.

Thus, with Struts (regardless of whether I use ActionForm(s) or


DynaActionForm(s)), I have 3 places to maintain parameter names.
Without Struts, I can cut this to only 2 places (JSP and business object).

If I understand this properly, Struts requires me to re-define the parameter


in the xml file(or in an ActionForm), despite the fact that it already
receives the information in the request
(request.getParameterNames()).

Is there a way in Struts to avoid this apparently unnecessary step and make
this more generic? Perhaps we need a DynaDynaActionForm :-)

Re[3]: ActionForm to handle dynamically generated fields


Author: Balaji Chakilam
(http://www.jguru.com/guru/viewbio.jsp?EID=1237045), May 11, 2005
Cant we do the same with out using the DynaActionForms... i am in urgent
need. please help me out.

Re: ActionForm to handle dynamically generated fields


Author: ashu tosh (http://www.jguru.com/guru/viewbio.jsp?EID=1157815), Mar
26, 2004
Chan I am in the same difficult situation need help. How was the problem solved.
How did you capture the generic field values, when there is no corresponding field
in the Action Form. If any one knows the solution please do reply As soon as
possible

Not certain why this is difficult


Author: S Edwards (http://www.jguru.com/guru/viewbio.jsp?EID=1210822), Nov 12,
2004
I have managed to solve this problem a couple of times, starting in Struts 1.0.2. One
mechanism for "open-ended" forms is to simply have the bean properties defined that
are always going to be present, and then have Lists, or Maps, for the properties that
might be variable. You will not be able to rely on the "input" attribute of the struts-
config file for repopulating your form unless you point your input at a Struts Action
that will repopulate the form select lists etc.

Another mechanism to handle is to have your mapped backed form, but pass in meta
data that defines which properties on the form are going to be rendered in as which
type of control. The JSP can then have an iterator and test in it to determine for this
element of the meta data, how does it need to be rendered. The Action would need to
take care of supplying the appropriate extra data (select lists) and repopulating that on
a validation error (you might consider just doing the validation inside the action rather
than leaving it up to the Struts Servlet).

Re: Not certain why this is difficult


Author: nith ps (http://www.jguru.com/guru/viewbio.jsp?EID=1211897), Nov 29,
2004
can U give sample code for this..

How can I use the "options" tag with a collection of options stored in my
ActionForm bean?
Location: http://www.jguru.com/faq/view.jsp?EID=549097
Created: Nov 16, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by kriss j (http://www.jguru.com/guru/viewbio.jsp?EID=531542

The properties for options are very confusing, and there's talk on DEV of an alternate
tag, optimized to use something like the LabelValue beans.

Here's how to use the current options tag when the LabelValue collection (from the
Example) has been stored as a property on the ActionForm. If you want to provide
the collection through an ActionForm method, you need to define a scripting variable
first.

<bean:define id="myOptions" name="donorForm"


property="myOptions" type="java.util.Collection"/>

Then

<html:select property="image">
<html:options collection="myOptions" property="value"
labelProperty="label"/>
</html:select>
If you wanted to build the list from a static method in your business layer, a simple
one could look like this:

public static String getMyOptions(int image) {


String text = null;
switch (image) {
case -5: text = "Photograph item"; break;
case -4: text = "Clip from Website"; break;
case -3: text = "Expect by email"; break;
case -2: text = "Expect by mail"; break;
case -1: text = "Do not use"; break;
case 0: text = "No"; break;
case 1: text = "Yes"; break;
case 2: text = "Use icon"; break;
}
return text;
}

public static Collection getMyOptionss() {


Collection list = (Collection) new ArrayList();
for (int i=-5; i<2; i++) {
list.add(new LabelValueBean(
getMyOptions(i),
String.valueOf(i)
));
}
return list;
}

Then in the ActionForm, a wrapper method can be used:

public Collection getMyOptions() {


return app.StaticClass.getMyOptions();
}

HTH - Ted

Comments and alternative answers

Typo?
Author: Chad Woolley (http://www.jguru.com/guru/viewbio.jsp?EID=759258), Mar
1, 2002
Is the following method supposed to be named ending with two letter "s's":
public static Collection getMyOptionss()

If so, shouldn't the following code be changed to use the "two-s" version:

public Collection getMyOptions() {


return app.StaticClass.getMyOptions();
}

Or maybe it's a typo, and you are intending to override the method? If this is the case,
maybe you could give them different names to make the example a little clearer?

Thanks,
Chad

how would the setter in the form look like for a Collection attribute ?
Author: Cezar Balaita (http://www.jguru.com/guru/viewbio.jsp?EID=797949), Mar
15, 2002
I would assume it should be :
public void setMyOptions(Collection coll) { this.coll = coll; }

If the validation of the form on submission fails, will this method be called
automatically ? If yes, what values will it look for ? Cezar

property="image" ?
Author: Dan Desch (http://www.jguru.com/guru/viewbio.jsp?EID=827173), May 31,
2002
Mr. Husted, in your example, you define a struts select tag thus: <html:select
property="image"> What does the property="image" attribute setting do in this
context? Also, can I infer from this example that your ActionForm bean is called
"donorForm"?

Thank you
Author: Damon Torgerson (http://www.jguru.com/guru/viewbio.jsp?EID=912164),
Jun 24, 2002
This example saved my bacon. Thanks!!!!

selected
Author: Paul Beccio (http://www.jguru.com/guru/viewbio.jsp?EID=983565), Sep
16, 2002
To add on that example - can you nest a logic:match or some other tag to use the
selected option? Thanks!

Re: selected
Author: mickey barton
(http://www.jguru.com/guru/viewbio.jsp?EID=1114085), Sep 9, 2003
How do you set multiple options as selected using
"<html:select>"
"<html:options />"
"</html:select>"

I've have it set up so that I can select multiple items from the list but I have not
been able to find any documentation on how to preselect some of the items
when I first display the page. Any idea on how to do this?

Thanks in advance. Mickey

Re[2]: selected
Author: Priya Selva
(http://www.jguru.com/guru/viewbio.jsp?EID=1109586), Oct 30, 2003
I have the similar problem described by Mickey.
I have to pre-select multiple values in the <html:select> tag which is
retrieved from the database.
Can anyone help me please
Thanks
Selva

Here's the real deal:


Author: Mike O'Connor (http://www.jguru.com/guru/viewbio.jsp?EID=1037209),
Dec 12, 2002
What a confusing answer! :o)

If you've stumbled across this page hoping for an answer to the question posed - here
it is:

Basics:

You have an ActionForm class, say, the class com.mycom.ClientForm, which has
the name "clientForm" (defined in your struts-config.xml in the form/form-bean tag).
You have a jsp, say, "client.jsp" and it's here where you want to use your options
tag.

Here's what to do:


In the ClientForm class, make a Collection of beans - one for each item in the select
drop-down list. The beans that you put in your Collection have to be objects of a bean
class that contains two properties - a "screenName" and an "id", where:

screenName is the String that is shown to the user for a particular option, and
id is the internal ID used to represent that option.

here's an example of such a bean class:

===========================================================
package com.finalist.util.struts;

/** This class is a bean, used to represent one option in an HTML


drop-down
* 'select' list. It contains two properties - see {@link
getDisplayName()} and
* {@link getInternalId()} for a description. Useful in a struts Form
class
* for constructing a select list to pass to the jsp with the
* <tt><html:select></tt> and <tt><html:option></tt> tags.
*
* @author Michael O'Connor - Finalist IT Group.
*/
public class HtmlSelectOption implements java.io.Serializable {

private String id;


private String displayName;

/** Creates an HtmlSelectOption with the specified property values.


*@param id the internal ID.
*@param displayName the displayName. */
public HtmlSelectOption() {}

/** Creates an HtmlSelectOption with the specified property values.


*@param id the internal ID.
*@param displayName the displayName. */
public HtmlSelectOption(String id, String displayName) {
this.id = id;
this.displayName = displayName;
}

/** Retrieves the 'display name': this is the name for this option
that
* is shown to the system user through the presentation layer
* (the <tt>labelProperty</tt> attribute of the <tt><html:option></tt>

* struts tag).
* @return the display name for this option. */
public String getDisplayName() { return displayName; }

/** Retrieves the internal ID: this is the ID that is used internally
* by the application to identify this particular option.
* (the <tt>property</tt> attribute of the <tt><html:option></tt>
* struts tag).
* @return the internal id for this option. */
public String getId() { return id; }

/** Sets the display name.


* @param displayName the displayName. */
public void setDisplayName(String displayName) { this.displayName =
displayName; }

/** Sets the internal Id.


* @param internalId the internal Id. */
public void setId(String internalId) { this.id = id; }

===========================================================

OK, so now you have the bean class. Now you make the Collection of beans.. In the
ClientForm class, for example, you could make the following static ArrayList of
HtmlSelectOption beans:

private static final ArrayList SEX_LIST;


static {
SELECT_LIST = new ArrayList(2);
SELECT_LIST.add(new HtmlSelectOption("M", "Man"));
SELECT_LIST.add(new HtmlSelectOption("F", "Woman"));
SELECT_LIST.add(new HtmlSelectOption("T", "Transexual"));
}

Next, in the ClientForm class, you need to make a getter method for a Collection
property that allows access to the SEX_LIST you just created:

public Collection getSexList() { return (Collection) SEX_LIST; }

OK so far - we're finished with the ClientForm class. Now in the JSP you need to
declare the "sexList" property of the form class (which itself is a bean), with the
following struts tag:

<bean:define id='sexList' property='sexList' name='clientForm'/>

Then finally there's the options tag itself:

<html:select size="10" property="sex">


<html:options collection="sexList" labelProperty="displayName"
property="id"/>
</html:select>

A little explanation to finish off:


The property "sex" in the html:select tag above is (let's say) a property "sex" of the
clientForm - so you can imagine corresponding getSex() and setSex(String sex)
methods in the form class. It's this property that will have the values "M", "F" or "T"
that you declared in the static ArrayList in the ClientForm class.
The labelProperty="displayName" refers to the fact that the property of the bean we
use (HtmlSelectOption bean) to access the display name of the option is
"displayName", and the HtmlSelectOption bean property "id" is the property that
contains the ID used to refer to the option.

Hopefully this clarifies things! I spent too long having to figure this out today myself..

Mike O'Connor

Re: Here's the real deal:


Author: Muralidhar Reddy
(http://www.jguru.com/guru/viewbio.jsp?EID=1053754), Feb 25, 2003
Hi Mike,
I've defined everything as u said and i have a loginForm(ClientForm)
as in ur case.and thats defined in the struts-config.xml
.and i displayed in the jsp as u said
. <bean:define id='userList' property='myCollection' name='loginForm'/>
and the options are decleared as follows
<html:select size="10" property="loginName">
<html:options collection="myCollection" labelProperty="displayName"
property="id"/>
</html:select>
. But on displaying in the browser i'm getting following exception
Error Message: Cannot find bean loginForm in scope null
Error Code: 500
Target Servlet: null
Error Stack: javax.servlet.jsp.JspException: Cannot find bean loginForm in scope
null.
Can u tell where have i commited mistake
.Your help is very much appreciated

Re[2]: Here's the real deal:


Author: Michael Glenn
(http://www.jguru.com/guru/viewbio.jsp?EID=1060667), Feb 25, 2003
Muralidhar,

I ran into the same error. It means that it can't find the bean logicForm, which
probably means that your bean definition tag (bean:define) isn't within the
associated form bean (form:bean) tag.

At least, that's the problem I experienced. It's also possible that loginForm isn't
properly defined in struts-config.xml.

Re[2]: Here's the real deal:


Author: Bill L (http://www.jguru.com/guru/viewbio.jsp?EID=1189464), Jul
29, 2004
I moved the bean tag and it worked for me.

<html:form action="/clientSubmit" focus="user">


<bean:define id='sexList' name='clientForm' property='sexList'/> .. ..

Re: Here's the real deal:


Author: jyoti verma (http://www.jguru.com/guru/viewbio.jsp?EID=1085285),
May 15, 2003
Mike, I did exactly what you said but I get an exception when I try to run my
program saying: No getter method for property sexList of bean ClientForm Any
suggestions?
Re[2]: Here's the real deal:
Author: Adam Gresh (http://www.jguru.com/guru/viewbio.jsp?EID=1061463),
Jun 5, 2003
Jyoti, I had the same problem at first, but figured it out by creating a form bean
first, then creating the collection bean. This showed me that the problem
wasn't in the options tag, but something wrong with the way I was creating the
bean.

After some debugging it seems that I named the property incorrectly...? I'm
actually not sure what I did exactly but in the end I wound up with code that
looked like...

<bean:define id="singleSelectOptionsBean"
name="altControlsForm"
property="testSelectSingleOptions"/>

<html:select property="testSelectSingle"
fieldeditflag="editTestSelectSingle">
<html:options
collection="singleSelectOptionsBean"
property="key"
labelProperty="value"/>
</html:altselect>

...where altControlsForm is my action form and the method


getTestSelectSingleOptions in AltControlsForm returns a Collection (an
ArrayList actually). HTH

Re: Here's the real deal:


Author: h p
(http://www.jguru.com/guru/viewbio.jsp?EID=1094323),
Jul 7, 2003
Hi
I have a problem which is similar to the one you
exaplained.
I have a parent JSP in which I am getting a vector of
questions dynamically, depending on the database
results. I am iterating over the questions vector and
finding the answertype of the question from the database
and depending on the answertype of the question I am
including the appropriate JSP(like select.jsp,radio.jsp
etc..)
here is the code snippet for the select.jsp

<html:select name="ans" property="aSelect">


<%
for (int j = 0, jSize = optns.size(); j < jSize; j++)
{
opt = (Option) optns.elementAt(j);
out.println(" the options are :"+opt);
%>
<html:option
value='<%=opt.getOptionNumber()%>'>
<%=opt.getOptionText()%>
</html:option>
<%
}
%>
</html:select>

here in the above I am using optns vector which


is there in parent jsp. so I am doing include
"<%@include file ="select.jsp"%>" in the
parent JSP.

here is my parent JSP


<html:form action="/getresult" >
<logic:iterate id="eachquestion" indexId="qid"
name="qGrp" property="questions"
type="com.officemax.configurator.Question" >
<div class="question">
<bean:define id="questext"
name="eachquestion"
property="questionText"/>
<h3><bean:write name="eachquestion"
property="questionText"/></h3>
<bean:define id="optns" name="eachquestion"
property="options" type="java.util.Vector"/>
<bean:define id="ansType"
name="eachquestion" property="answerType"
/>
<% System.out.println(" Answer Type =
"+eachquestion.getAnswerType());%>
<logic:equal name="ansType" value="radio">
<%@include file ="radio.jsp"%>
</logic:equal>
<logic:equal name="ansType" value="select">
<%@include file ="select.jsp"%>
</logic:equal>
<logic:equal name="ansType" value="text">
<%@include file ="text.jsp"%>
</logic:equal>
<logic:equal name="ansType"
value="checkbox">
<%@include file ="checkbox.jsp"%>
</logic:equal>
<html:hidden
value='<%=eachquestion.getQuestionText()%>'
property="qText" />
</div>
</logic:iterate>
<html:submit>
Submit </html:submit>
when I hit submit I have to capture the question
text and the selected option , so that i will have
to use ActionForm in another JSP where I
should display the questions and selected
option for that.

I have to solve this problem very soon. Thank


you very much in adavance.

Can We Avoid JSP's in Struts FrameWork Hi,

Can We use Servlets to Paint Screen instead of JSP's in Struts Framework, if


Yes What are its Disadvantages,Modifications needed etc...

Thanks Renny Jose


Location: http://www.jguru.com/faq/view.jsp?EID=568117
Created: Nov 30, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by Renny Jose Thoppil
(http://www.jguru.com/guru/viewbio.jsp?EID=565154

The response object is passed to the Action perform method. You can use this to
write your own response to the client, in the usual way. The standard Struts "reload"
action does this to paint "OK" to screen after reloading the mappings.

For fancier pages, the best thing would be to have your servlet answer to it's own
URI pattern. The Struts Action could then forward to that, the same as it does with
JSPs.

Your serlvet can then look in the request context for the ActionForm, or whatever
other objects you will use, and render the response from that. If your servlet just
does what the HTML tag extensions do, then the rest of the framework will be none
the wiser. And all they really do is populate the HTML control using the properties of
an ActionForm found in the request context.
The other resources used by the tag extensions, like the mappings and messages,
are available in application scope, so your servlet could use those too, if needed.

On an incoming request, the ActionServlet sets the values on the ActionForm bean
via reflection. It doesn't now or care how the values got into the HTTP request. It's
just looking for name=value pairs in the HTTP request that match the property
names on the designated ActionForm.

The tag extensions know to look for the ActionForm in the request context, or
instantiate one if it's missing. The latter part is so any default values can be given to
the HTML controls. The tags also know how to look into the mappings to find out
which ActionForm goes with which Action, but that's added value. You can always
code that part by hand (and at one point, we did).

But so long as the names of the HTML controls match the ActionForm names, it
doesn't matter who writes the HTML. HTTP is the great equalizer.

The JSPs are not tightly coupled with the framework, and anything they do could be
done by another servlet. It is helpful, though, if your serlvet answers to its own URI
pattern, as the JSP service does. Architecturally, this then makes it a drop-in
replacement for JSPs.

I understand that there is a renewed interest on the Jakarta Velocity list about using
their servlets with Struts. The strategies they use would probably work for you too.

HTH -Ted

Browsers reload button and url writing Hello, here is my problem :


JSP1 -> ActionClass1 -> ActionClass2 ->JSP2
When I'm on the JSP2, the url is that of the ActionClass1, so when I hit the
reload button, the ActionClass1 is reloaded. (and I would like the
ActionClass2 to be reloaded).
How can I do ?
Location: http://www.jguru.com/faq/view.jsp?EID=705837
Created: Dec 31, 2001
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by jn dl (http://www.jguru.com/guru/viewbio.jsp?EID=466056

The reload button, by definition, is suppose to resubmit the last request. In this case,
you would not like the last request to be resubmitted and reprocessed the same way.
You would like ActionClass1 to skip ahead and forward the request to ActionClass2.

A good strategy to tell if a request has already been submitted is to use "tokens".
Struts supports this directly with various *token methods in the Action class. To
implement this, you would go back to "ActionClass0" that lead to JSP1. In this
Action, put

saveToken(request) ;
Then in ActionClass1 put a call to
isTokenValid(request)
If the token is not valid, you would want to forward to ActionClass2
If it is valid, you would want to finish the usual processing in ActionClass1 and call

resetToken(request);
to signal that the token has been used.

-Ted.

Comments and alternative answers

Auto-refresh in IE 5.5
Author: Nils Svensen (http://www.jguru.com/guru/viewbio.jsp?EID=796595), Mar
14, 2002

Is it possible to avoid the alert "The page cannot be refreshed without resending the
information. Click retry..." in IE when using automatic periodic refresh and struts?

I am using the token mechanism to check if the page is refreshed, and do not perform
the action (check isTokenValid in the action class) if it is a refresh.

JSP1->ActionClass1->JSP1

The first time the JSP is loaded, the action in ActionClass1 is performed and the JSP
page is again loaded. When hitting the refresh button after this, though, the alert box
appears (beacuse of the form values). I do not want this to happen, because I want a
possibility to automatically refresh the page periodically (also after the action has
been performed once). Is this possible?

Submitting forms as a collection Using the <logic:iterate> tag i'de like to


format several rows of recurring data for a user to change or add some
values.

When the data is submitted back to the Action routine I see how it can
arrive as an Action form.

Is there a way to submit the results as a collection of forms instead?

Thanks,

Mitch
Location: http://www.jguru.com/faq/view.jsp?EID=710844
Created: Jan 6, 2002
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by Mitch Dresdner
(http://www.jguru.com/guru/viewbio.jsp?EID=390316

HTML browsers can only submit results pursuant to the HTTP protocol. So everything
comes in a hashtable of Strings.
There is a nice nesting pacakge for Struts that might help you organize the
collections so that they can be submit back as Strings and put back into your
collection

See Nested Struts Extension for details.

HTH -Ted.

Comments and alternative answers

Any plans to add this to Struts?


Author: Markus Neifer (http://www.jguru.com/guru/viewbio.jsp?EID=592820), Jan 8,
2002

This would be very useful to handle the display of a shopping card in a shop
application. Currently i have no idea how to generate the name for the input field
(quantity) in each row.

Markus

Re: Any plans to add this to Struts?


Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042), Jan
8, 2002

Since Struts is component-based, adding another taglib like this is an expected


part of the development process. So, if you put it in your /web-inf/lib folder,
bingo, it's part of Struts ;-)

Meanwhile, the author has offered to donate the Nested Taglib to the Apache
Software Foundation, and it is likely that it will be accepted into the Struts
subproject. There is currently other development going on in the CVS right now
which might affect this package, and so it has not been proposed to the nightly
build quite yet.

-Ted

Re[2]: Any plans to add this to Struts?


Author: Alex Lindgren
(http://www.jguru.com/guru/viewbio.jsp?EID=293396), Aug 3, 2002
I've noticed that this is now in the 1.1 beta.

http://jakarta.apache.org/struts/userGuide/dev_nested.html
One solution (for struts 1.1 beta?)
Author: Richard Wan (http://www.jguru.com/guru/viewbio.jsp?EID=953512), Jul 17,
2002
I was putting together a toy "shopping cart" app and ran into the "user updates a
collection" problem and came up with the following solution:
on the form bean:
public QuoteFormLineItem[] getLineItems() {...}
public QuoteFormLineItem getLineItem(int index) {...}

on a the line item: int getQuantity() and setQuantity(int q)

on the jsp:

<logic:iterate id="lineItem" property="lineItems"


name="quoteFormBean">
<tr>
<td>
<html:text name="lineItem" property="quantity"
indexed="true"/>
</td>
<td>other stuff...</td>
</tr>
</logic:iterate>

the main drawback was that the id for the iterate tag had to match the name of the
indexed getter on my form bean. I was under the impression that the id used in a .jsp
page could be considered flexible and independent of the applicaiton code.

Re: One solution (for struts 1.1 beta?)


Author: Placid Sea (http://www.jguru.com/guru/viewbio.jsp?EID=1139814), Feb
16, 2004
I m still confused. Cud u plz explain how exactly this piece of code works? and
"QuoteFormLineItem" is what? I wud appreciate if u elaborate more.

Re[2]: One solution (for struts 1.1 beta?)


Author: Ron Rossier (http://www.jguru.com/guru/viewbio.jsp?EID=1176099),
Jun 3, 2004
I think I can help ... The example does work, once u understand that u have to
create another bean class called QuoteFormLineItem
public class QuoteFormLineItem implements Serializable
{
//Declarations
private int quantity;
public QuoteFormLineItem () {
}
//get/set
public int getQuantity() {
return quantity;
}
public void setQuantity(intquantity) {
this.quantity= quantity;
}

Re[3]: One solution (for struts 1.1 beta?)


Author: vs y (http://www.jguru.com/guru/viewbio.jsp?EID=1176496), Jun
5, 2004
In my Action class ,I added multiple form beans to collection and had set
that collection on a method on the same form bean.

quoteFormlineItems is an ArrayList

quoteFormlineItems.add(quoteFormBean);

quoteFormBean.setQuoteFormLineItems(quoteFormlineItems);

In my formBean QuoteFormBean ,I have following code:


private ArrayList quoteFormLineItems;

public void setQuoteFormLineItems(ArrayList lineItems) {

this.quoteFormLineItems = lineItems;

public ArrayList getQuoteFormLineItems() {

return quoteFormLineItems;

}
on the jsp , I used iterate.Till here I have no problem.I am getting the
values displayed.
I my Action class after submitting I have the following code to retiieve the
collection of formbeans:
quoteFormBean.getQuoteFormLineItems

I tried printing the size of collection and I get 0 printed


when my collection has 2.Cud u plz let me know what I am doing wrong.

Re[4]: One solution (for struts 1.1 beta?)


Author: Ashish Dave
(http://www.jguru.com/guru/viewbio.jsp?EID=1191917), Aug 10, 2004
if possible send me code on nesting in struts...

Re[4]: One solution (for struts 1.1 beta?)


Author: Ed Coughlin
(http://www.jguru.com/guru/viewbio.jsp?EID=1252163), Jul 6, 2005
Hi, I'd appreciate obtaining the example source as well. It is mostly
there but I think i might be missing something. Thanks, Ed

Re: One solution (for struts 1.1 beta?)


Author: Joe Nelson (http://www.jguru.com/guru/viewbio.jsp?EID=1207151), Oct
25, 2004
How would this be written if I'm using DynaActionForms?

Re[2]: One solution (for struts 1.1 beta?)


Author: swami ganesan
(http://www.jguru.com/guru/viewbio.jsp?EID=1241602), Apr 28, 2005
Hello, Can I also have the full sample code by email, please Thanks in advance
Swami Ganesan g_swaminathan@hotmail.com

Re: One solution (for struts 1.1 beta?)


Author: Kelly Ann Alvares
(http://www.jguru.com/guru/viewbio.jsp?EID=1247397), Jun 6, 2005
Hi,
I'm still using struts 1.0 (and can't upgrade at this moment) is there a way to
implement your solution with struts 1.0 ?
thanks,
Kelly.

What is URI? Can anybody help me What is URI please?


Location: http://www.jguru.com/faq/view.jsp?EID=741075
Created: Jan 30, 2002
Author: Pierre Sirolli (http://www.jguru.com/guru/viewbio.jsp?EID=724553)
Question originally posed by Bhaskar Kommuru
(http://www.jguru.com/guru/viewbio.jsp?EID=709748

A URI can be further classified as a locator, a name, or both. The


term "Uniform Resource Locator" (URL) refers to the subset of URI
that identify resources via a representation of their primary access
mechanism (e.g., their network "location"), rather than identifying
the resource by name or by some other attribute(s) of that resource.
The term "Uniform Resource Name" (URN) refers to the subset of URI
that are required to remain globally unique and persistent even when
the resource ceases to exist or becomes unavailable.
The following examples illustrate URI that are in common use.
ftp://ftp.is.co.za/rfc/rfc1808.txt
-- ftp scheme for File Transfer Protocol services

gopher://spinaltap.micro.umn.edu/00/Weather/California/Los%20Angeles
-- gopher scheme for Gopher and Gopher+ Protocol services

http://www.math.uio.no/faq/compression-faq/part1.html
-- http scheme for Hypertext Transfer Protocol services

mailto:mduerst@ifi.unizh.ch
-- mailto scheme for electronic mail addresses
news:comp.infosystems.www.servers.unix
-- news scheme for USENET news groups and articles telnet://melvyl.ucop.edu/ --
telnet scheme for interactive services via the TELNET Protocol

how to use a href in struts JSP? hi all, i try to pass dynamic data using a
href but it seems fail to work in struts.

original JSP:

<href="/callfile.do?action=w&filename=<%=bean.getFILENAME()%>">

Struts JSP:

<html:link
page="/callfile.do?action=w&filename=<%=bean.getFILENAME()%></ht
ml:link>;

i can't get the <%=bean.getFILENAME()%> value when using struts.can


anyone help?

regards, CY
Location: http://www.jguru.com/faq/view.jsp?EID=741079
Created: Jan 30, 2002
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by Ong CY (http://www.jguru.com/guru/viewbio.jsp?EID=447528

The html:link tag is designed so that you can do that without resorting to scriptlets.
Try:
<html:link page="/callfile.do?action=w" paramName="bean"
paramProperty="FILENAME" paramId="filename"/>

(Though, you may have problems unless the accessor is named getFilename, per the
conventions.)

{soapbox}

Personally, I discourage use of the page form of html:link, and always use global
forwards instead. This way all the entry points to your application are documented,
and you don't have to expose API features like "action=w" in the JSP. You can give
the action=w forward a logical name, and use that instead.

In struts-config:
<forward="callW" path="/callfile.do?action=w"/>
In your JSP:
<html:link forward="callW paramName="bean" paramId="filename"/>

In my own applications, the only place I expose the name of another Action is in the
html:form tags (and I'm working on that;-)

{/soapbox}
HTH - Ted

Comments and alternative answers

buttons?
Author: blinky bill (http://www.jguru.com/guru/viewbio.jsp?EID=863602), May 2,
2002
The forward looks neater. One other question though, is there a simple way in struts
for the link to show as a html [button] rather than as a standard hyperlink. Or do I
need to use javascript on a button to do this?
eg. setting window.location or something?

using HREF with struts - case sensitive issues


Author: Aidan Coughlan (http://www.jguru.com/guru/viewbio.jsp?EID=990908), Aug
29, 2002
Hi, Ive just starting using struts and have struggled for I wont say how long with
getting a href to work. I had a request parameter on the href something like: ..
href="/AgentStatusDetail?AgentName=OMSAGENT002.... Struts correctly located
and executed the AgentstatusDetailAction, but when debugging through this code the
AgentName parameter simply wasnt there. After much frustration, taking a lead from
the struts sample application, I tried making the parameter "AgentName" to lowercase
"agentname" , changing the references throughout the application, and it worked ! I
havent experimented further to prove it, but I wonder if there may be some case
sensitive issues with struts ? I notice that FILENAME is spelt uppercase in one of the
posts here - if you are reading this & experiencing similar problems, it may be worth
trying lowercase parameter names. Note: the get/set methods on the ActionForm class
will still be getAgentname, and setAgentname (capital A only).

Re: using HREF with struts - case sensitive issues


Author: marc foley (http://www.jguru.com/guru/viewbio.jsp?EID=1029250), Nov
22, 2002
I am trying to do something very similiar and I am not having any luck.

<html:link
page="/servlet/changeSearch?adv=N&tab=<%=request.getParameter("tab")%>">

any thoughts?

Re[2]: using HREF with struts - case sensitive issues


Author: sl Yong (http://www.jguru.com/guru/viewbio.jsp?EID=1024371), Jan
11, 2003
Hi I would like to know whether you have any luck with ur problem

Re[2]: using HREF with struts - case sensitive issues


Author: Claudiu Dobre
(http://www.jguru.com/guru/viewbio.jsp?EID=957289), May 20, 2003
It's a bit late to answer this :) but I'l try.

Personally I like more the HTH - Ted's solution. I had a similar problem and
one solution could be that

<html:link page='<%= "/servlet/changeSearch?adv=N&tab=" +


request.getParameter("tab") %>' >

which acctually is not very nice.. :(

here is the solution in my style


Author: Ajay Kumar (http://www.jguru.com/guru/viewbio.jsp?EID=1205911),
Oct 18, 2004
I have couple of values displayed by the bean when I iterate and I need
hyperlinks to all of them which are dynamic and each hyperlink has a unique
value. And I need to pass two parameters when the user clicks on it. So the
following way I am able to capture both the parameters from the action form.
try this it works. I have spend alot of time on it. And I got 2 other ways of
doing it. Let me know if you need further assistance. <form
name="selectForm" action="/sv/jsp/client.do" method="post">
<input type="hidden" name="svId" value="Bill">
<input type="hidden" name="request" value="0">

<logic:iterate id="searchDetails" name="sv_container"


property="searchResults">
<bean:define id="param1" name="searchDetails" property="svId"/>
<a href="/sv/jsp/client.do?request=0&svId=<%=param1 %>"> <bean:write
name="searchDetails" property="name"/> </a>
</logic:iterate>

-Ajay Kumar

A small follow up to Ted's answer.


Author: John Munsch (http://www.jguru.com/guru/viewbio.jsp?EID=236478), Dec
17, 2002
I just wanted to comment that the <forward> Ted refers to creating in the struts-
config.xml file is in the global forwards section. I had thought that the forward would
be within one of my action mappings because the link I was creating on the page was
inside of one of the forms on that page.

In fact, the location of the link on the page didn't matter, the forward it referred to had
to be listed in the global forwards.
Any update on using Global Forward in Form Action?
Author: Anthony Law (http://www.jguru.com/guru/viewbio.jsp?EID=882127), Dec
23, 2002
Guru Ted Husted wrote:

"In my own applications, the only place I expose the name of another Action is in the
html:form tags (and I'm working on that;-)"

Hi all I'm just curious if this is implemented yet? I tried using a recent nightly build &
got:

Cannot retrieve mapping for action /myGlobalForward'

multiple dynamic values to global forwards


Author: Bapi Reddy (http://www.jguru.com/guru/viewbio.jsp?EID=1165380), Apr 23,
2004

How do i send multiple dynamic values to the global forward


action using the <html:link forward....tag

Re: multiple dynamic values to global forwards


Author: Himabindhu Kunz
(http://www.jguru.com/guru/viewbio.jsp?EID=1247742), Jun 8, 2005
Hi
Here is the solution.
you can pass multiple query string parameter properties by specifying a map with
the name attribute demonstrated as follows:

<% java.util.HashMap newValues = new java.util.HashMap();


newValues.put("floatProperty", new Float(444.0)); newValues.put("intProperty",
new Integer(555)); newValues.put("stringArray", new String[] { "Value 1", "Value
2", "Value 3" }); pageContext.setAttribute("newValues", newValues); %> ...

and then passing this to the link tag

<html:link action="/html-link" name="newValues"> Float, int, and stringArray via


name (Map) </html:link>

the Java scriptlet creates a HashMap and sticks the HashMap into page scope
under the attribute newValues. The link tag links to an action and specifies the
HashMap as its list of query string parameters with the name attribute.

Cheers
Bindhu
Maintaining form data across pages... I am trying to setup a series of jsp
pages (jsp1, jsp2, jsp3). Each of these adds or modifies properties (or
collections) of object customerForm(supply name/address, add contacts,
etc.) This is an "experimental" app I'm putting together to try out struts.

In struts-config.xml, I have the choice of setting the scope parameter for


each action mapping. If I set scope to "request", then customerForm is
instantiated each time the form is presented - data is lost across forms.

If I set to "session" then I can maintain the data across the various forms,
but customerForm.reset() is still called.

My questions:

What is the best way to maintain the customer data across several jsp
pages?
Should I just move form data to a customer bean from customerForm
each time?
Should I just display data from the current customer bean rather than
from customerForm?

Jeff.
Location: http://www.jguru.com/faq/view.jsp?EID=749741
Created: Feb 6, 2002
Author: Jason Rosenblum (http://www.jguru.com/guru/viewbio.jsp?EID=740621)
Question originally posed by Jeff Sprenger
(http://www.jguru.com/guru/viewbio.jsp?EID=740521

here's an example: you have an HTML form. after it is filled out the user previews
the results on a second JSP and then chooses to submit or edit the HTML form again.
If the user submits, then he is forwarded to a confirmation page. In order to process
this you do: 1) cache ActionForm in session after form submission. 2) I pass my
Customer bean to the preview page via request. I was able to construct a Customer
bean by calling a toXXXX() method in my ActionForm (e.g. toCustomer). 3) on the
confirmation page i query the database and return the results as a Customer bean
passed via request. I also clean out session using removeAttribute(). I hope that
helps...
Comments and alternative answers

Not so clear!
Author: Reza Naqshbendi (http://www.jguru.com/guru/viewbio.jsp?EID=806149),
Mar 21, 2002
I mean for me! I've been tearing my hair out about this and I've supposed there should
a way whithin Struts itself to pass the data from pages without me saving them here
and there and pass them around. The official doco recommends to use 'one big form
for many pages, actions'. In this case there should be way to avoid that
reset() being triggered on session forms and clearing up the data already populated.

Need a better way


Author: Howard Frost (http://www.jguru.com/guru/viewbio.jsp?EID=891608),
May 24, 2002
I've also had this problem in a different scenario.

My ActionForms (DynaActionForms actually) contain all the fields necessary to


paint the page and collect the results. Not all the information used to paint the
page is submitted (e.g. population of a dropdown list).

When the form is submitted and the Action detects a validation error it is overly
difficult to repaint the page.

If the Action forwards back to the JSP page, the JSP tag which paints the
dropdown errors out because reset() cleared this data.

If the Action forwards to the Action which originally painted the page, the User's
submitted information needs to be carefully overlayed on the initial screen paint
data.

It should be possible to specify DynaActionForm properties to be left un-reset.


This way, Action can safely forward back to the JSP page.

Re: Not so clear!


Author: Mike Melia (http://www.jguru.com/guru/viewbio.jsp?EID=122959), May
29, 2002
Make reset() check if the data has been completed (i.e. all attributes not null)
before resetting them to null. That way the data is not reset until it is necessary.

Re[2]: Not so clear!


Author: Dean Chen (http://www.jguru.com/guru/viewbio.jsp?EID=899352),
May 31, 2002
I don't think you can change the behavior of reset in a DynaActionForm.

Re[3]: Not so clear!


Author: Mike Melia
(http://www.jguru.com/guru/viewbio.jsp?EID=122959), Jun 2, 2002
Maybe so, but I wasn't replying to the message that mentioned the
DynaActionForm ;)

Re[4]: Not so clear!


Author: scott naef
(http://www.jguru.com/guru/viewbio.jsp?EID=1242955), May 6, 2005
You can extend the DynaActionForm and overide the reset method as
needed...

Use html:hidden tags to re-populate the form.


Author: Artur de Sousa Rocha (http://www.jguru.com/guru/viewbio.jsp?EID=70489),
Dec 20, 2002
If you don't have an outrageous number of fields or special data (like passwords), you
can use <html:hidden> tags to keep the data across pages. The only multi-page
feature you will have to implement will be smart validation that knows which data to
check on a given page.

Regarding passwords, just use separate single-page forms for password entry. The
same applies to file upload.

You can cheat and make the fields static.


Author: Brian Grant (http://www.jguru.com/guru/viewbio.jsp?EID=1052551), Jan
31, 2003
This will allow all forms to see only the fields you want to be accessible accross
you forms.

Re: You can cheat and make the fields static.


Author: Danilo Gurovich
(http://www.jguru.com/guru/viewbio.jsp?EID=1061840), Feb 28, 2003
Doesn't this violate thread safety?

Re[2]: You can cheat and make the fields static.


Author: yayo yayez
(http://www.jguru.com/guru/viewbio.jsp?EID=1222082), Mar 9, 2005
Yes I think it breaks thread safety because they're different beans but same
class... I Use html:hidden to store data among several pages and the reset
tricky I think that could be solved extending dynaforms

Handling multi page form beans


Author: ravi kalidindi (http://www.jguru.com/guru/viewbio.jsp?EID=1232513), Mar
14, 2005
I had a similar situation where I needed to share the same form bean across multiple
pages - similar to a wizard like page flow.

The basic concepts for this are:

• use one form bean with all the attributes.


• The action class at the end of the wizard flow can copy the values into state
beans before passing them to the business tier.
• keep the form bean in "session" scope
• do NOT implement the default "reset" method.
• create your own resetXXX methods that can be called from the action classes
as needed. For an example, go to my posting on Manning Sandbox
Submission
• make sure you control the flow so that a "Cancel" button removes the form
bean from the session.

Thats it. You get to use the same form bean in all the pages and will be uptodate with
the modifications the user makes. For input types such as checkboxes that need resets,
do so in a smart way.

All the best!


- Ravi

Re: Handling multi page form beans


Author: Kiran Chandra (http://www.jguru.com/guru/viewbio.jsp?EID=1233000),
Mar 16, 2005
I have a question regarding uploading a file using DynaActionForm. I am not sure
if the form value is getting reset but it just doesn't seem to work. Here's the code
for reference. It is an extension to the example by James Turner at
http://www.developer.com/java/ent/article.php/3321521 with an additional field
called fileone of the type FormFile in the bean. Everything works fine except the
upload feature. The fileone property is set to null somehow and cannot be
retreived in the action instance. I would highly appreciate any feedback on the
same. Sorry to send you the link since I think that it better explains what I am
doing than pasting all the code myself. Please reply if you get a chance. Kiran

Switching the locale(language) of an application via a button on a page.

How can you change the locale of an application via a button on a web page.
I am using struts and don't want the user to have to change their language
from the browser (e.g. Tools-Internet Options-Languages in IE).

I want the user to be able to toggle languages from a button! This toggling
only needs to be held throughout the lifecycle of the user's session. When
the session ends the application will automatically use the browsers default
language when a page is requested.

Location: http://www.jguru.com/faq/view.jsp?EID=749742
Created: Feb 6, 2002
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by Chris Lawson
(http://www.jguru.com/guru/viewbio.jsp?EID=733866

Struts places a locale object in the application scope, and it's just a matter of
changing that.

David has a nice example in his sample Validator application.

HTH - Ted

Comments and alternative answers


Locale in Session
Author: Thomas Qvarnstrom (http://www.jguru.com/guru/viewbio.jsp?EID=761801),
Feb 17, 2002
I should change the Locale in the application scope since that may effect other user.
Instead use this piece of code in your ActionForm:
session.setAttribute(org.apache.struts.action.Action.LOCALE_KEY, new
java.util.Locale("","") );

Re: Locale in Session


Author: Steve Leung (http://www.jguru.com/guru/viewbio.jsp?EID=939919), Jul
6, 2002
I have tested on the David's sample Validator application.
http://home.earthlink.net/~dwinterfeldt/archive/validator20020114.zip. I try to add
new Locale of "zh". First time, I type some chinese characters in property file and
save as ApplicationResources_zh.properties without use native2ascii.exe. The JSP
parser fail to compile it in run time. Second time, after I use native2ascii on the
properties file. It success compile but only display ?? instead of chinese
characters. Is this a bug ? I suspect that struts read the correct properties file but
use the wrong encoding methods on String. Remarks: my browser use [en-us]
encoding. I press the link to change locale to zh. Anyone know the problem ?

Re[2]: Locale in Session


Author: John Jiang (http://www.jguru.com/guru/viewbio.jsp?EID=1017744),
Nov 6, 2002
Hi steve,

Since you already converted the resource file with native2ascii, I guess you
need to set the encoding of the jsp page to UTF-8.

<%@page language="Java" contentType="text/html; charset=UTF-8"%>.

get downloaded struts-validator.war


Author: abhishek shrivastava
(http://www.jguru.com/guru/viewbio.jsp?EID=1219583), Jan 25, 2005
hi........ get the struts-validator.war and go to the examples... it will surely help u... the
same thing implemented here.. Good luck... Abhishek

select tag and options tag. How do I use the same info, but different
variables? I followed the example previously given by Ted, allowing me to
fill an options tag from a database, use helper classes. I have a situation
where two select/option tags are filled from the same bean call. The
following code is just under my <html:Form>

<bean:define id="titles" name="DocRegForm" property="title"


type="java.util.Collection"/>
<bean:define id="specs" name="DocRegForm" property="spec"
type="java.util.Collection"/>
below I have the following:
Specialty #1
<html:select property="spec">
<html:options collection="specs" property="value"
labelProperty="label"/>
</html:select>

Specialty #2
<html:select property="spec">
<html:options collection="specs" property="value"
labelProperty="label"/>
</html:select>
I need to differentiate between Specialty#1 and Specialty#2. How can I do
this? If I change the select property it tells me it cannot find the getter
method. Must I have two different methods simply to allow me to pass two
different pieces of information? If I leave it the way it is, I get two "spec"
variables in my "GET".
Location: http://www.jguru.com/faq/view.jsp?EID=756521
Created: Feb 12, 2002
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by josef richberg
(http://www.jguru.com/guru/viewbio.jsp?EID=715417

HTML does allow parameters with duplicate name, and Struts will captures those like
any other property if an array is used.

private String[] spec = {"",""};


public String[] getSpec() {
return this.spec;
}
public void setSpec(String spec[]) {
this.spec = spec;
}

HTH -Ted

More control with <html:errors/>

I know you can specify header and footer in the prop file, but what if
different pages have different needs in terms of displaying errors. E.g., In
some cases its a list and in others I want sentences strung together with no
header.

What if I want to list out errors but don't want to user

<ul>...</ul>
?

Are there code examples of how to use the

<html:errors/>
more extensively than currently described in the documentation?
Location: http://www.jguru.com/faq/view.jsp?EID=756562
Created: Feb 12, 2002
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by John Crossman
(http://www.jguru.com/guru/viewbio.jsp?EID=12222

The message tag in the nightly build offers more flexibility

This might also be available in the Struts Validator library

The other alternative is leave the errors header and footer blank, so you can add the
HTML yourself.

To test for the presence of error messages in Struts 1.0.x, you can use

<logic:present name="org.apache.struts.action.ERROR">

And then wrap (or not wrap) the messages with markup

To retrieve individual messages, you can specify the property in the html:error tag.

But, the new messages tag really does a much better job of this.

HTH -Ted

Comments and alternative answers

See html:messages, not bean:message


Author: Jerome Jacobsen (http://www.jguru.com/guru/viewbio.jsp?EID=65688), Oct
3, 2002
To clarify, Ted is referring to the new html:messages tag, not the bean:message tag.

The html:messages tag is more flexible and generic than the html:errors tag. It
can display messages "stored as an ActionMessages object, ActionErrors object, a
String, or a String array".

Displaying information about the field in error


Author: Krishna Kumar (http://www.jguru.com/guru/viewbio.jsp?EID=1025653),
Nov 16, 2002
Using html:messages or logic tags, is it possible to output a header for each property
which has errors attached to it, without explicitly coding a html:messages block for
each property?

I have a form which has several fields, which are validated in the Action class. These
errors are added to the ActionErrors collection with the field's property name, for
example,
errors.add("myFirstField", new Action Error(...);

Now, in the jsp, it is possible to produce an output such as

Errors for My First Field


<error1 text>
<error2 text>

Errors for My Third Field


<error1 text>

I would like to do this without repeating a


<bean:message key="myfirstfield.error.header" />
<html:messages id="error" property="myFirstField">
<bean:write name="error" />
</html:messages>

block for each property in the form as (a) this would be error prone, programmers
may miss to put this block for all the properties in the form and (b) if this can be done
without reference to specific form's properties, then this generic code can be pulled
into each page via some kind of include or template mechanism.

Thanks in advance for any hints.

Answer for More control with html:errors/ I know you can specify header and
footer in the prop file, but what if ....
Author: pahiappan singaravel
(http://www.jguru.com/guru/viewbio.jsp?EID=1238466), Apr 14, 2005
In the properties file you can simply remove the headers and footers and add the html
tags wherever you want. like errors.Login.use=<b>username required<b>

Any html:multibox samples out there?

Hi, can anybody please point me to a working sample using html:multibox?

Retrieving the values out of my form bean works well using a getter method
which returns an array of String. However, having a setter method which
takes an array (Collection) doesn't work.

Thanks in advance.

Markus

Location: http://www.jguru.com/faq/view.jsp?EID=756568
Created: Feb 12, 2002
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by Markus Neifer
(http://www.jguru.com/guru/viewbio.jsp?EID=592820

ActionForm:

private String[] selectedItems = {};


private String[] items = {"UPS","FedEx","Airborne"};
public String[] getSelectedItems() {
return this.selectedItems;
}
public void setSelectedItems(String[] selectedItems) {
this.selectedItems = selectedItems;
}

JSP:

<logic:iterate id="item" property="items">


<html:multibox property="selectedItems">
<bean:write name="item"/>
</html:multibox>
<bean:write name="item"/>
</logic:iterate>

HTH -Ted

Comments and alternative answers

It works!
Author: Markus Neifer (http://www.jguru.com/guru/viewbio.jsp?EID=592820), Feb
15, 2002

Yes, this works. But one should not forget to add the 'name' attribute to the
logic:iterate start tag. Well, just copy and paste is never a good idea, right?! ;-)

Thanks, Ted.

Markus

Re: It works!
Author: Eduardo Troncoso
(http://www.jguru.com/guru/viewbio.jsp?EID=1027323), Nov 19, 2002

To me, don't work. Weblogic (6.1) show this exception


message:
javax.servlet.jsp.JspException: No getter method for property selectedItems of
bean org.apache.struts.taglib.html.BEAN at
org.apache.struts.util.RequestUtils.lookup(RequestUtils.java:517) at
org.apache.struts.taglib.html.CheckboxTag.doStartTag(CheckboxTag.java:205) at
jsp_servlet.__eliminar_usuario._jspService(__eliminar_usuario.java:167) at
weblogic.servlet.jsp.JspBase.service(JspBase.java:27) at
weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:265
)...

What wrong !?

Re[2]: It works!
Author: samaria camarena
(http://www.jguru.com/guru/viewbio.jsp?EID=1101903), Jul 16, 2003
Hi, I got a similar error. Did you get a solution for your error? Regards!!! 500
Internal Server Error javax.servlet.jsp.JspException: No getter method for
property value of bean item java.lang.Object
org.apache.struts.util.RequestUtils.lookup(javax.servlet.jsp.PageContext,
java.lang.String, java.lang.String, java.lang.String)

Re: It works!
Author: paul mclachlan (http://www.jguru.com/guru/viewbio.jsp?EID=1049850),
Jan 27, 2003

I have defined the "name" in the iterate Tag but I get the following exception.
What have I failed to do?

As I see it I add the code into the ActionForm defined to be associated with the jsp
in the appropriate action-mapping struts-config.xml

javax.servlet.jsp.JspException: Cannot find bean null in any scope


java.lang.Object
org.apache.struts.util.RequestUtils.lookup(javax.servlet.jsp.PageContext,
java.lang.String, java.lang.String, java.lang.String) int
org.apache.struts.taglib.logic.IterateTag.doStartTag() void
_Landowner._jspService(javax.servlet.http.HttpServletRequest,
javax.servlet.http.HttpServletResponse)

Re[2]: It works!
Author: srinivas reddy
(http://www.jguru.com/guru/viewbio.jsp?EID=1249961), Jun 23, 2005
did u ensure that the name is the same one that you used in your struts config
file, or else it is going to fail ex: <action path="/xxxForm" type="xxxxAction"
name="test" input="/jsp/test.jsp" validate="true"> <forward name="valid"
path="/jsp/xxx.jsp" /> </action> The name that you use for iterate should be
"test"

Re: It works!
Author: eric lee (http://www.jguru.com/guru/viewbio.jsp?EID=947775), Mar 5,
2003
Was this works even without defining public String[] getItems() in your Action
Form? Anyway, I am having item bean not found in any scope error. and idea?
Eric

Can this use collections instead of arrays?


Author: Mike Park (http://www.jguru.com/guru/viewbio.jsp?EID=849301), Apr 22,
2002
can I have an ArrayList of objects instead of an array? ActionForn -> private
ArrayList ethnicity=new ArrayList(); + getter and setter jsp -> <logic:iterate
id="item" property="items"> <html:multibox property="ethnicity"> <bean:write
name="item"/> </html:multibox> <bean:write name="item"/> </logic:iterate> What
if my arrayList contained non-string objects (KeyNamePair, a key-value mapper that
is less than a hash map entry, that maps string -> string, boolean->string or int-
>string), will the array list be populated with only the selected items? Mike

Re: Can this use collections instead of arrays?


Author: Lim BH (http://www.jguru.com/guru/viewbio.jsp?EID=920254), Jul 8,
2002
Hi Mike, I have the same question as you. Did you get any answer for the question
you posted? Can you share them with me? Thanks, Lim

Re[2]: Check all / Uncheck all


Author: HELIGON Sandra
(http://www.jguru.com/guru/viewbio.jsp?EID=823885), Apr 1, 2003
Has someone the solution to allow the user to check all the elements of the
table in only one order ? Is the treatment made only side client by a Javascript
or one requests from the web server?

Re[2]: Can this use collections instead of arrays?


Author: Murali Vasudevan
(http://www.jguru.com/guru/viewbio.jsp?EID=1104105), Jul 25, 2003
I have used a collection of LabelValueBean to generate checkboxes with
values different from the labels. It is very important that you specify the name
attribute (the ActionForm name) in the iterate tag.

org.apache.struts.util.LabelValueBean is available from STRUTS 1.1.

If anyone is interested, I can give you the code.

The same approach may work for a group of radio buttons too.
Re[3]: Can this use collections instead of arrays?
Author: Roberto Silva
(http://www.jguru.com/guru/viewbio.jsp?EID=1118009), Sep 25, 2003
Hi Murali, I´d like to receive your example code. I´m trying to do that
using a Vector and your code may be helpfull. Thanks.

Re[3]: Can this use collections instead of arrays?


Author: Rajesh H (http://www.jguru.com/guru/viewbio.jsp?EID=1135662),
Dec 24, 2003
I am using dynaactionform for our application and the jsp page has
multibox which is being dynamically generated, i need to know how to set
the multibox marked when the user retrives the previously avilable record
from the database. Please pass me your code for the above said
functionality. Regards H.Rajesh hrajesh3@ford.com

Re[3]: Can this use collections instead of arrays?


Author: Seema Bhujbal
(http://www.jguru.com/guru/viewbio.jsp?EID=1179365), Jul 7, 2004
hi i would like to receive your code.Thanking in advance.

Re[3]: Can this use collections instead of arrays?


Author: Awadh Pandey
(http://www.jguru.com/guru/viewbio.jsp?EID=1189916), Nov 4, 2004
Hi Murali, I am new to Struts and I am finding it hard to follow all
recomendation. I would very much appreciate if you could share your jsp
code and associated java code. I have been able get the multibox example
running with the static array text in the form bean class. I would like to
generate the array dynamically in the jsp code itself. and it does not work.
cheers and thanks in advance, Awadh awadh@pmdashboard.com.au

Initialization
Author: Juliane Scheider (http://www.jguru.com/guru/viewbio.jsp?EID=1107989),
Aug 12, 2003
How can I initialize a Multibox, that it will be marked?

Multibox
Author: Latha Rao (http://www.jguru.com/guru/viewbio.jsp?EID=1157483), Mar
25, 2004
Did you find a solution to this problem? I am trying to
display a page with all of the Multiboxes checked. The
Multibox is generated dynamically and so I cannot
determine ahead of time what the size or the values will be.

Example...
Author: A O (http://www.jguru.com/guru/viewbio.jsp?EID=1156324), Mar 22, 2004
all is there : http://j2ee.lagnada.com/struts/multibox-example1.htm a very good
example

another example using LabelValueBeans


Author: A O (http://www.jguru.com/guru/viewbio.jsp?EID=1156324), Mar 22, 2004
Another interesting example using an existing struts Bean : LabelValueBeans
http://www.johntopley.com/kb/java/0027.html

Re: another example using LabelValueBeans


Author: Banana Flo (http://www.jguru.com/guru/viewbio.jsp?EID=1161451), Apr
15, 2004
Can anyone provide the Action that is necessary for John's example?

Struts Multibox and mySql


Author: Marco Assini
(http://www.jguru.com/guru/viewbio.jsp?EID=1224524), Feb 1, 2005
I have a similar problem: JSP: <form:checkbox property="topicsid"
value="<%out.println(topics[i][0]);%>"/> where topics[i][0] is a integer (this
works, I hope!) GETTER and SETTER private String topicsid[] = new
String[this.getK()]; public String[] getTopicsid() { return (this.topicsid); }
public void setTopicsid(String topicsid[]) { this.topicsid = topicsid; } where k
is the right lenght of the array ACTION String[] topicsid = ((NewusersaeForm)
form).getTopicsid(); String id_topic1 = Integer.toString(topicsid.length); int
id_topic2 = Integer.parseInt(topicsid[1]); MY PROBLEM and ERROR:
id_topic1 and id_topic2 should go in a mySql database as Integer: id_topic1
with the length of the array works, but id_topic2 doesn't! Thanks to everybody

In order to run Struts, do I need to install a servlet container such as


Tomcat?
Location: http://www.jguru.com/faq/view.jsp?EID=771298
Created: Feb 25, 2002
Author: Aron Tunzi (http://www.jguru.com/guru/viewbio.jsp?EID=446077) Question
originally posed by Nguyen van Tin
(http://www.jguru.com/guru/viewbio.jsp?EID=761500

Yes, you must!

See the installation requirement for Struts:


http://jakarta.apache.org/struts/userGuide/installation.html

I found the following methods in Action.java which I think may help to


control the session ID. That means if the user submits the page and press
the back button and submit the page again it will throw an error.

generateToken(HttpServletRequest request)
saveToken(HttpServletRequest request)
isTokenValid(HttpServletRequest request)
If anybody has used these methods let me know how to use these methods .

Thanks,
Subhendu

Location: http://www.jguru.com/faq/view.jsp?EID=779112
Created: Mar 2, 2002
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

Before going to a page you want to protect, route to an Action first and call
SaveToken. This stores a token with a unique value in the user's session.

If the page uses the html:form tag, it will automatically include a hidden field with
the token if it finds one in the session.

In the Action that receives the page, use isTokenValue to see if the token in the
session matches the one from the form. Call resetToken to clear the token, so it can't
be used again.

HTH -Ted.

Comments and alternative answers

Tokens for Transaction Control : How do you gracefully handle the error case?
Author: Jerome Jacobsen (http://www.jguru.com/guru/viewbio.jsp?EID=65688), Oct
3, 2002
I've seen the Struts 1.1b2 example's use of the Token for transaction control
technique. This is in EditRegistrationAction and SaveRegistrationAction.

However, I'd like to know if there is a more robost solution to this problem. I'd like
the ability to ignore the second posting and still return the results from the first. That
is, act as if the second posting never occurred. Is there a way to do this?

The problem with the Example's approach is that the user doesn't really know what to
do next after the error is displayed. They don't get their display results from the first
posting. How do they know it succeeded?

Re: Tokens for Transaction Control : How do you gracefully handle the error
case?
Author: René Vangsgaard (http://www.jguru.com/guru/viewbio.jsp?EID=585009),
Mar 19, 2003
I know this is an old question, but have you checked the recent article on
JavaWorld on this issue?
Note: JavaWorld is unavailable at the moment, so I cannot supply the link.

Re[2]: Tokens for Transaction Control : How do you gracefully handle the
error case?
Author: Glen Blanchard
(http://www.jguru.com/guru/viewbio.jsp?EID=1090702), Jun 3, 2003
The JavaWorld article you are referring to is this I think
http://www.javaworld.com/javaworld/javatips/jw-javatip136.html

Re[3]: Tokens for Transaction Control : How do you gracefully handle


the error case?
Author: Xiaolong Hao
(http://www.jguru.com/guru/viewbio.jsp?EID=1087550), Aug 13, 2003
I am not sure the solution provided in this tip solves the problem. I looked
at the source code (by the way, the source code is quite different from the
segment of code in the article), I cannot find the logic to handle the case of
the following sequenct: 1) the first request is sent to server 2) the execut()
is invoked 3) before the execut() finishes, the same request is sent to server
again. It seems to that it only handle the case that the same request is sent
after the first request finishes.

Token concurrency issue


Author: René Vangsgaard (http://www.jguru.com/guru/viewbio.jsp?EID=585009),
Mar 19, 2003
Assume that the execute() method of a Struts action contains the following:
if (isTokenValid(request)) {
resetToken(request);
// Guarded code, must only be executed once for the current
token.
}
What happens, if two requests from the same client (that is, the requests belongs to
the same session) enters the action at the same time, and...

1. Thread A executes isTokenValid(request), which evaluates true.


2. Thread B executes isTokenValid(request), which also returns true, as thread A
hasn't run resetToken() yet.
3. Both thread A and thread B enters the "guarded" code block.

How do I ensure that only one request per request per session executes the "guarded
code"?

Re: Token concurrency issue


Author: Scott Carlson (http://www.jguru.com/guru/viewbio.jsp?EID=1085622),
May 17, 2003
use isTokenValid(request,true), which synchronizes on the Session before it does
the reset.

Re[2]: Token concurrency issue


Author: Joaquin Almansa
(http://www.jguru.com/guru/viewbio.jsp?EID=1171714), May 20, 2004
Hi,
One question about isTokenValid(..., true).
I suppose token is only resetted if token is valid.
Is it so?
If not, we may be loosing a valid submit which happens later.
For instance:
1. Form1 is marked ok with the current token, token1.
2. User bookmarks an old form, Form0, marked with token0.
When evaluating Form0 submit, if we reset token (I understand there's only
one per session at a time), when Form1 is submitted we will think it is invalid.

Does token mechanism works like this?

Thanks in advanced,

Joaquin.

Re[3]: Token concurrency issue


Author: George Thomas
(http://www.jguru.com/guru/viewbio.jsp?EID=1261012), Sep 5, 2005
When multiple requests come to server they will be managed by different
threads.
For request1 it will call a add/edit page where we will save a token and on
save action we check whether the token is there then save the values and
reset the token.So that if the user clicks on back button and again try to
save,multiple records with same values will not be generated.

Even if Request2 comes at same time it will proceed independent of


request1 since each are different threads and proceed independently.

When we save a token it gets stored in a request scope (and not session
scope),so it will be for the particular request that token will be having a
value till that request ends.So when it submits it checks for that token and
resets it if already present and saves the data.All this process must be inside
if(isTokenValid)loop. If the token has been destroyed just forward to next
page without any save operation

do we have a jsp tag doing the same thing as Action's saveToken?


Author: Amit Rana (http://www.jguru.com/guru/viewbio.jsp?EID=1116177), Sep 18,
2003
Ted said -- Before going to a page you want to protect, route to an Action first

Is it possible to start from a JSP? does any of the available tags provide the same
functionality?

Regards.
How works the "/admin/reload.do" in struts? Hi!
Looking in the struts documentation i found the class ReloadAction, I
though that this class reload the struts-config.xml and the application
resources without restart the appserver (in my case Tomcat 4.0)...
I want do this because i want modify the MessagesResources file, but when
i modify the file and call /admin/reload.do, it updates everything except the
MessagesResources file!!
I`m doing something wrong or what?
Please help Me!
PS: There is another way to do it? I mean, update the MessagesResources
file?
Location: http://www.jguru.com/faq/view.jsp?EID=779194
Created: Mar 2, 2002
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by Adolfo De Unanue
(http://www.jguru.com/guru/viewbio.jsp?EID=765312

The ReloadAction reloads and reparses the Struts configuration files. The resource
bundle used by the MessageResource file is not actually part of the configuration, so
it is not reloaded. Some containers do automatically reload property files, but this is
not a Struts specific features. It would apply to any Web application using standard
resource bundles.

A question to ask in the Tomcat circles might then be "How to configure Tomcat to
reload resource bundles when they change.".

HTH -Ted

Comments and alternative answers

There apparently is no support for reload in 1.1b. Are there plans to add it?
Author: Dean Chen (http://www.jguru.com/guru/viewbio.jsp?EID=899352), May 31,
2002
There apparently is no support for reload in 1.1b. Are there plans to add it?

Re: There apparently is no support for reload in 1.1b. Are there plans to add
it?
Author: Mohammad Rizwan
(http://www.jguru.com/guru/viewbio.jsp?EID=989793), Feb 5, 2003
Can u tell me how to configure tomcat , so that
it loads properties file everytime it changes?

...forcing reload of resource bundles


Author: Andrew Hart (http://www.jguru.com/guru/viewbio.jsp?EID=1063965), Mar
6, 2003
see also:
http://www.jguru.com/faq/printablefaq.jsp?topic=I18N

Author: Kevin Schaaf (http://www.jguru.com/guru/viewbio.jsp?EID=466729), Sep


10, 2001
You can implement this non-standard way of refreshing all resource bundles in the
VM as follows:
Class klass = ResourceBundle.getBundle
("resources.framework").getClass().getSuperclass();

Field field = klass.getDeclaredField("cacheList");

field.setAccessible(true);

sun.misc.SoftCache cache = (sun.misc.SoftCache)field.get(null);

cache.clear();

[...]

Re: ...forcing reload of resource bundles


Author: Axl Kaross (http://www.jguru.com/guru/viewbio.jsp?EID=1153725), Mar
12, 2004

does this still work? I couldn't get any bundle for resources.framework (Can't
find bundle for base name resources.framework, locale de_DE)

if i'm using fully qualified classname of my application properties, the bundle is


found. but that doesn't seem to work either for reloading

Re[2]: ...forcing reload of resource bundles


Author: Ed Kusnitz (http://www.jguru.com/guru/viewbio.jsp?EID=1208990),
Nov 3, 2004
It didn't work for me either. The code found the SoftCache but nothing got
refreshed.

But there is an easier way. Just create your MessageResources from a new
MessageResourcesFactory. That's where the cache apparently is. HTH --Ed

Re: ...forcing reload of resource bundles


Author: V. Ananth (http://www.jguru.com/guru/viewbio.jsp?EID=952581), Oct
20, 2004
I tried this in my application it is showing the errors, is that the code u tried in
your application
The Life of An ActionForm

Hi,

I'm trying to setup a form that will populate with the information about a
user (their name, address, etc.) I'm having trouble with this because I don't
really understand how the ActionFormBeans work.

When are they created and destroyed? When is the reset() method called?
Should I call it myself or does Struts do it for me? What about the
validate() method? Is it only triggered when I call it in my code?

I have seen some forms that create the ActionForm bean in one action that
creates the populated form page, and then uses another action to store the
data in the model. How do I set this up? Will the reset() method not be
called before I want it to?

If someone could please clear up the life cycle of an ActionForm bean I


would appreciate it. Thanks!

Location: http://www.jguru.com/faq/view.jsp?EID=827776
Created: Apr 6, 2002
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by Mark Bennett
(http://www.jguru.com/guru/viewbio.jsp?EID=753558

Struts uses ActionForms to both populate a HTML form, and then to capture the
parameters when a form is submitted.

When a request is submitted, the ActionServlet matches the URI for the request
against the path of an action-mapping. If there is a form-bean for that action-
mapping, it looks for an ActionForm under the form-bean name. If it doesn't find
one, a new one is created. The ActionServlet then calls reset() on the new or pre-
existing ActionForm and populates it from the request. If the action-mapping has
validate set to true, the ActionServlet calls the validate method. If this returns any
error messages, the ActionServlet forwards to the URI indicated by the action-
mappings error property. This is often a JSP, but it can also be another action-
mapping. The latter being needed when there are drop-down controls to populate
and so forth. If there are no errors, the ActionServlet passes the (populated and
validated) ActionForm to the Action indicated by the action-mapping element.

When a JSP with an html:form tag is rendered, the html:form tag uses its action
path to look-up its action-mapping. Like the ActionServlet, it uses the form-bean to
check for a ActionForm in the appropriate servlet context. If it doesn't find one, it
creates one. The new or pre-existing ActionForm is then used by the other html:tags
to populate their elements.

It's important to note that the form-bean name is used as the default attribute
name. Another attribute name can be specified in the action-mapping if needed.
Likewise, the html tags default to using the ActionForm related to the html:form tag,
but any bean can be specified for any html tag element (ActionForm or not).

When passing ActionForm beans between Actions it is important to note that the
ActionServlet will try to populate it again between Actions. If you modify a value, you
must be sure to protect it from autopopulate or reset. One way to do that is to add a
mutable switch to your ActionForm bean. See SuperForm for an example

HTH, Ted

Comments and alternative answers

Lifetime of an ActionForm (continued...)


Author: Keshav Deshpande (http://www.jguru.com/guru/viewbio.jsp?EID=243878),
Apr 14, 2002

Ted:

From what I gather from your comments as well as the SuperForm implementation, it
allows me to make the form mutable/immutable but ONCE and only ONCE within a
user session.

But what if I need to make the form mutable dynamically within a single session,
given that I have only one instance of the ActionForm?

Consider the following example:


While implementing "search" functionality, I have two navigation paths to the
SearchParametersForm, where a user would enter search parameters. Firstly, the user
may wish to perform an entirely new search. Secondly, the user may wish to modify
existing search parameters.

In the second scenario the idea that an ActionForm maintains the form state works
quite well in that, I can go back to the form and find that the form values are all
maintained between requests (but within a session).

But the problem arises when I want a user to start over within the same session, i.e. I
want to clean out any and all priorly entered values on the ActionForm.

How do I accomplish this?

Any ideas/suggestions would be deeply appreciated...

Example of Implementing Superform


Author: Anand Jayaraman (http://www.jguru.com/guru/viewbio.jsp?EID=854980),
Apr 25, 2002
Ted: I just started on struts and was looking @ your superform.
I have a code in my JSP

<html:text property="programName" size="40" maxlength="40"/>

How will have the "programName" go after the getter method in the SuperForm
getProperty with a Parameter as "programName"

Thanks,

ActionForm Lifecycle.
Author: Rick Small (http://www.jguru.com/guru/viewbio.jsp?EID=1054935), May
28, 2003
Ted, when you state:

"When a JSP with an html:form tag is rendered, the html:form tag uses its action path
to look-up its action-mapping. Like the ActionServlet, it uses the form-bean to check
for a ActionForm in the appropriate servlet context. If it doesn't find one, it creates
one. The new or pre-existing ActionForm is then used by the other html:tags to
populate their elements. "

Isn't there a call to reset() in this sequence? I'd just like to confirm that the reset()
method is supposed to be called on a 'new' ActionForm before it is used to populate
the html:form?

Rick

Re: ActionForm Lifecycle.


Author: abhishek shrivastava
(http://www.jguru.com/guru/viewbio.jsp?EID=1219583), Jan 6, 2005
hi..., ya ...reset method is called automatically everytime by the ActionServlet
before populating the ActionForm bean properties.so u need not to call it
explicitly.... good luck.. Abhishek

SuperForm has been moved to CVS attic


Author: Patterson Waltz (http://www.jguru.com/guru/viewbio.jsp?EID=1147262), Aug 5,
2004
Find it here… http://cvs.apache.org/viewcvs.cgi/jakarta-
struts/contrib/scaffold/src/framework/main/org/apache/scaffold/http/Attic/SuperForm.java

Re: SuperForm has been moved to CVS attic


Author: Bala Paranj (http://www.jguru.com/guru/viewbio.jsp?EID=505521), Jan
12, 2005
Why not just over-ride the reset method with a empty method?

Confused
Author: Saritha V (http://www.jguru.com/guru/viewbio.jsp?EID=1055612),
Jan 27, 2005
Confused with the what I have been observing while working with
Action Forms and
with its strange behavior and after reading all the posts abt
action forms and reset behavior.

I would like to know how data is populated into ActionForms?


From all above posts, I understand that ActionServlet populates
the ActionForm when it process new request or when it renders
JSP page.
I wanted to know what is the source for the ActionServlet to
populate ActionForm?. I think it is request.
Can some one please explain me how this works in a pictorial
format?
JSP to Action
JSP to action to Action

Thank you
Your input woiuld be a great help to me..

Re: Confused
Author: Jyothi Rajesh
(http://www.jguru.com/guru/viewbio.jsp?EID=1245093), May 20, 2005
Hi,

Check out this site.

http://rollerjm.free.fr/pro/Struts11.html#2

This gives a considerable UML diagrammatic view of the how struts


works.

-Jyothi

Passing values from a Collection to Action class Hello Friends, getter and
setter functions of form bean work properly. also using the iterator tag, i am
able to show values on the jsp page. but when the user changes those
values and the control goes to the action class, the values are not changed
inside the list. can any one explain why, or an alternative way of doing it, or
struts does not support this and has to be done thru response object.
Thanks, Suresh.
Location: http://www.jguru.com/faq/view.jsp?EID=827781
Created: Apr 6, 2002
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by Suresh Bansal
(http://www.jguru.com/guru/viewbio.jsp?EID=814148

If the list you are displaying is represented as an array, then it should be repopulated
from the request. The usual way to go about handling duplicate parameters is
private String[] items = {"",""};
public String[] getItems() {
return this.item;
}
public void setItem(String item[]) {
this.item = item;
}

In the form, you can then write out the array out using the iterate tag

<logic:iterate name="logonForm" property="items" id="item">


<TR>
<TD>Item:</TD>
<TD>
<input type='text' name="item" value='<bean:write name="item"/>'></TD>
</TR>
</logic:iterate>

HTH, Ted

Comments and alternative answers

solved my hidden multibox problem


Author: Nic Daniau (http://www.jguru.com/guru/viewbio.jsp?EID=881099), Aug 6,
2002
this answer helped me solve the question I had re' passing hidden data from page to
page originally captured using a multibox.

if the multibox storage array (held in the action form bean myForm) is String[]
items, it can be passed from JSP to JSP using:

<logic:iterate id="item" name="myForm" property="items">


<input type="hidden" name="items" value="<bean:write
name="item" />">
</logic:iterate>

thanks Ted!

Re: solved my hidden multibox problem


Author: Mel N (http://www.jguru.com/guru/viewbio.jsp?EID=1183029), Jul 1,
2004
I want to do exactly what you did ie. pass hidden data from page to page that is
captured as the user ticks checkboxes. But your snippet of code does not work for
me.

Instead i get this error: org.apache.jasper.JasperException: No collection found

Is this because I'm trying to access an array and logic:iterator tag is looking for a
collection?

Please help! Thanks!

Setter methods not being called.


Author: Gayatri S (http://www.jguru.com/guru/viewbio.jsp?EID=988940), Aug 25,
2002
Yes i am also faing the same problem. I have an arraylist inside which is another
arraylist which contains (driverWidget) objects. After the jsp is displayed and user
puts in the values , the driverwidget objects are not being set. I am under the
impression taht the struts framework would care of this setting or do we explictly
have to call the set methods ? Thanks Gayatri

Displaying default values and returning changed


values.
Author: Michael Cardon
(http://www.jguru.com/guru/viewbio.jsp?EID=1018428),
Oct 28, 2002
The form bean:

private List items = new LinkedList();

private String[] fields = { };

public List getItems() {


return items;
}

public void setItems(List items) {


this.items = items;
}

public String[] getFields() {


return fields;
}

public void setFields(String[] fields) {


this.fields = fields;
}

Then in the form:

<logic:iterate name="beginFieldForm"
property="items" id="item" indexId="i">

<span <html:text size="25" name="beginFieldForm"


class="prompt"><bean:message property="fields" value="<%=
key="prompt.field" arg0="<%= ((ProfileData)item).getName() %>" />
String.valueOf(i.intValue() + 1) </logic:iterate>
%>" /> </span>

cheers Ted!
Author: Andy Morris (http://www.jguru.com/guru/viewbio.jsp?EID=1173290), May
26, 2004
You're answer was extremely easy to use, I've only been using struts for a few days
and you resolved one of my biggest worries! I used dyna action forms and so just
doing the struts iterate tag bit was simple. Only prob is that the fields are pre-
populated with some java array gobbledegoop, hopefully find a work around for this i
want them to be blank. If any1 knows how feel free to post, cheers again, andy

Struts with EJB Hi All, I have a set of EJBs written, I am planning to create a
prototype based on struts/MVC concept and I need to use some of the
Business Logic Beaans [entity/session beasn] in to prototype
implementation, please ealaborate me on this like where exactly those ejb
beans be implemented/plugged in to incorporate the business logic? Please
post to me @ mushtaqm@covansys.com Thanks & Regards, Mushtaq
Location: http://www.jguru.com/faq/view.jsp?EID=827784
Created: Apr 6, 2002
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by Mushtaq Mathur
(http://www.jguru.com/guru/viewbio.jsp?EID=812586

Generally, EJBs, or any type of business logic, would be called from the Action. Struts
brings the input in via the ActionForm bean, where it can be passed to the business
tier. When the business operation completes, the Action can react to the outcome
and indicate to the ActionServlet where to go next.

HTH, Ted.

Comments and alternative answers

Business Delegate
Author: Matt Smith (http://www.jguru.com/guru/viewbio.jsp?EID=838953), Apr 15,
2002
Look into the business delegate design pattern and have your actions talk to the
business delegate. By providing different implementations of your business delegate,
Provides a great way to test your web tier without hitting your ejbs.
HTH

Matt

ActionForms and Value Objects - Repetition of Code? I was very excited to


start using ActionForms and Struts' forms tag library in order to lower the
amount of code needed to handle all the forms in the current project I am
working on, but then someone came and told me that if we created one
ActionForm object for each form we had in the project, we would be
repeating code since all those fields in each ActionForm object already
existed in the application model's Value Objects.

I know we would be repeating code, but, in my point of view, the


ActionForm objects are more connected to the View than the Model, and are
a way of grouping all required data in a single place, so the Actions can
access them easily.

What do you think about this? Do you think they are correct by saying the
ActionForms are just a waste of time, and that they only make the
application bigger and more difficult to maintain? They are proposing a
solution of integrating the Value Objects with the Action Forms in some
manner... which sounds too much time-consuming to me, and might not
come to be a good solution at all. Less code doesn't always mean a better
solution!

Please state your opinions on this.


Location: http://www.jguru.com/faq/view.jsp?EID=827787
Created: Apr 6, 2002
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by Frederico Ferro Schuh
(http://www.jguru.com/guru/viewbio.jsp?EID=802994

Struts doesn't really need an ActionForm for every form -- it needs a form-bean for
every form. In most cases, you can simply define one master ActionForm for your
application, with all the properties it uses, and then register it under different form-
bean names. This will give each form its own attribute name in the servlet contexts,
so that you can have more than one form on a page without anything colliding. The
Struts-Validator also goes by the attribute name, so that you can have a different
formset for each form-bean, even if they all share the same ActionForm type. Worst
case, you can use a base "property bean" ActionForm and subclass it with different
validate methods, if needed.

While ActionForms may resemble value objects, they fill a very different purpose.
They are really buffers for the HTML controls, and give you a chance to validate
untrusted input before passing it along to value objects. HTTP is a wild protoocol and
exposing objects designed for another purpose to a Web browser may have
unforseen results. Also, HTTP is string-based, everything comes in as a string and
somebody has to cope with that.
See also
http://www.mail-archive.com/struts-user@jakarta.apache.org/msg19281.html
http://www.mail-archive.com/struts-user@jakarta.apache.org/msg19338.html
http://www.mail-archive.com/struts-user@jakarta.apache.org/msg20833.html

In Struts 1.1 beta, a Map can be used instead of individual properties on an


ActionForm. In the future, I foresee Struts developers using the same base
ActionForm in all their projects, without going through the hassle of defining all these
String properites.

HTH, Ted

Comments and alternative answers

Code Sample
Author: khien siow (http://www.jguru.com/guru/viewbio.jsp?EID=840887), Apr 16,
2002
Ted: Where can I find an example which is using a Map in ActionForm? Thanks.

Re: Code Sample


Author: shimon koifman (http://www.jguru.com/guru/viewbio.jsp?EID=755537),
Apr 24, 2002
The struts framework is very good for actions but very bad 4 forms and tags. its to
heavy for simpple tasks as tag libreries and request handling

Re: Code Sample


Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042), May
24, 2002

Since 1.1b

private Map values = null;

public void setValues(Map values) {


this.values = values;
}
public Map getValues() {
return this.values;
}

public void setValue(String key, Object value) {


getValues().put(key,value);
}
public Object getValue(String key) {
return getValues().get(key);
}
...

<html:text property="value(name)"/>

HTH -Ted

Re[2]: Code Sample


Author: Ivan Filipino (http://www.jguru.com/guru/viewbio.jsp?EID=929600),
Jun 26, 2002
Hi Ted,

I am having problem running this part of my jsp:

<html:text property="value(name)"/>

Am receiving the following exception message:

Exception thrown by getter for property value(name) of bean


org.apache.struts.taglib.html.BEAN

Do I need to set up anything in my struts-config.xml?

Thanks.

Re[3]: Code Sample


Author: Michael Civello
(http://www.jguru.com/guru/viewbio.jsp?EID=935119), Jul 2, 2002
I think he was implying that the JSP line would be inside a <nest> ref.
Looks like it doesn't know what object to access for the getter/setter. Try
setting the "name" too.

Re[3]: Code Sample


Author: Julio Peñuela
(http://www.jguru.com/guru/viewbio.jsp?EID=1127448), Nov 14, 2003
I'm getting exactly the same error: No getter method for property
value(nom) of bean org.apache.struts.taglib.html.BEAN
How can I solve this problem ? Thanks in advance.

Need help with ActionForms.


Author: Shashi MN (http://www.jguru.com/guru/viewbio.jsp?EID=1072996), Apr 3,
2003
Is it possible that in a ActionForm I have another class(created by me) variable as a
member?

Basically the problem is that I have a HTML table in a form and the columns of this
table are all input fields. I waould like to represent each row of this table by a class
instance!! This would mean that each row is represented by an instance of a class
which is a member of the ActionForm!! i.e. the ActionForm would have one member
as an array of objects.

Does such a thing work?? has anyone tried it before?


Shashikant.

Re: Need help with ActionForms.


Author: Anthony Tobianski
(http://www.jguru.com/guru/viewbio.jsp?EID=1226580), Feb 10, 2005
A little complex, but you could maybe use the value(property) type form and do
something like...
int i =0;
while( ) {

Stuff stuff = new Stuff();


stuff.setName( name );
myActionForm.put(new Integer(i).toString(), stuff);
++i;
}
On JSP maybe...
<bean:define name="current" property"value(1)">
<c:out value="${current.name}" /> < %-- or --%>
<bean:write property="current.name" />
There are propably alternative shortcuts for looping on the JSP not even touched
on here.

ActionForm and Value Objects


Author: Anthony Tobianski (http://www.jguru.com/guru/viewbio.jsp?EID=1226580),
Feb 10, 2005
We've started using the type of ActionForm spoken of here and it really keeps the
code base down on large projects. However, there is a downside you have to deal
with.

If you need JavaScript to do some custom validation, you have to make sure to give
the field an "ID", because JavaScript thinks "value(whatever)" is an attempt to call a
function. <c:out> does not like the "value(whatever)" syntax as well.

This leads to a problem I'm currently having. In the middle of my page I have data
retrieved from a database, which actually represents a paper form. I have any number
of "quantity" properties, so set them as "quant_1", "quant_2", etc. Now, I hard coded
the whole page because I know there are only 36 rows, but after doing some research
have found that the page is failing due to its compiled JSP size. I know how to loop
via <c:forTokens>, but not sure if I'll be able to place the <c:out> inside a
<bean:write> or any other tag, i.e....

<bean:write name="form"
property="value(quant_<c:out value=\"${row}\"/>)" />
So, I have to test the above and would appreciate any thoughts on how I might
process this section of my page, even a different way of storing it that would
correspond to an available collection iterator on the JSP. Your ideas would be greatly
appreciated!

Re: ActionForm and Value Objects


Author: java guy (http://www.jguru.com/guru/viewbio.jsp?EID=1138494), Apr 8,
2005
did u figure out yet ?
if theres a nicer way let me know...so far i've been doing the scriplet (i know....)
way .
<% String foo = "prop"+i ; %> <bean:write name="bar" property="<%foo%>"/>

handling errors in file upload with struts

I am using struts and have an upload.jsp and its associated


UploadForm.java and UploadAction.java. The jsp's form has an
enctype=multipart/form-data and contains an html:file field to upload a file
as well as a bunch of text fields for metadata associated with the file. If an
error occurs during validation, the struts controller servlet forwards to the
jsp with error messages. The problem is that the filepath the user specified
is no longer present. Is there a way to restore this value so the user doesn't
have to complete this field again (the other text fields remain filled in).
Location: http://www.jguru.com/faq/view.jsp?EID=877085
Created: May 13, 2002
Author: Ramon Gonzalez (http://www.jguru.com/guru/viewbio.jsp?EID=728508)
Question originally posed by Pat Marsland
(http://www.jguru.com/guru/viewbio.jsp?EID=296781

Not that I know of, but here is a simple solution using JavaScript

When a file is typed or selected using the "BROWSE" button, as soon as the field is
populated, a function populates a hidden input text field with the value of the file
name that was just selected. Whe you submit your form, you will have the name of
the file as part of your request.getParameters("file1name") in your UploadForm.java.

The problem is that the <INPUT TYPE-"file"> will not take a default value, even if you
try to force it thru JavaScript. I think this is probably a security feature in JavaScript
to avoid "hidden" file uploads from your PC, but you can display the path they
entered so they can cut-n-pate it into the INPUT field.

<INPUT TYPE="file" NAME="file1" SIZE="60" MAXLENGTH="60"


onchange='return file1Value(this)'>
<INPUT TYPE="hidden" NAME="file1name" VALUE="">

<SCRIPT LANGUAGE="JavaScript1.2">
function file1Value(thisvalue) {
thisvalue.form.file1name.value =
thisvalue.form.file1.value.toString();
return true;
}
</SCRIPT>
Comments and alternative answers

Excellent solution
Author: Nagaradjane Soundiramourthy
(http://www.jguru.com/guru/viewbio.jsp?EID=909398), Jun 10, 2002
My problem was, when I process the submitted form of type multipart/form-data I got
the servlet error stating that I can't mix methods of getParameter with
servletInputStream... I spent nearly half-a-day to find out the reason on the enctype of
multipart/form-data..ultimate outcome is no solution. But after I implemented your
suggestion, it worked great.. Really you have given excellent solution....

Anybody could Please provide : what are steps required to configure fileupload
using Struts ? in JSP/HTML
Author: jamesd JamesJacob (http://www.jguru.com/guru/viewbio.jsp?EID=970036),
Jul 30, 2002
Anybody could Please provide : what are steps required to configure fileupload using
Struts ? in JSP/HTML

Re: Anybody could Please provide : what are steps required to configure
fileupload using Struts ? in JSP/HTML
Author: Ramon Gonzalez (http://www.jguru.com/guru/viewbio.jsp?EID=728508),
Aug 16, 2002

The default Struts package has an example calles "Struts-upload". It is a demo


WAR package on how to upload files using Struts. Install and play with it.

Re: Anybody could Please provide : what are steps required to configure
fileupload using Struts ? in JSP/HTML
Author: Vladimir Coutinho
(http://www.jguru.com/guru/viewbio.jsp?EID=891959), Jul 27, 2003
There is a example in struts (struts-upload application). See it.

onchange event in IE5


Author: Polly Kidd (http://www.jguru.com/guru/viewbio.jsp?EID=1038223), Dec 16,
2002
This is a great idea, but i was a little flummoxed to find that the Javascript onchange
event didn't work as expected in IE5. It was called when the text in the file field was
altered by typing but not when another file was selected using the 'browse' button.

I got round this problem by substituting the onblur event for the onchange one: this
seems to work fine, i.e.

<html:file property="imageFile" onblur="return filenameValue()"/>

JUnit with singletons What do people think about adding the functionality
into JUnit to enable one to load and unload singletons during tests. This can
be very helpful, if, for example, several possible states of the singleton that
cannot be achieved in succession need to be tested. I've come up against it
recently. Perhaps using something like this:
http://developer.java.sun.com/developer/
TechTips/2000/tt1027.html#tip3
Location: http://www.jguru.com/faq/view.jsp?EID=877088
Created: May 13, 2002
Author: Janne Nykänen (http://www.jguru.com/guru/viewbio.jsp?EID=874437)
Question originally posed by Grisha Golberg
(http://www.jguru.com/guru/viewbio.jsp?EID=868035

Well, one way to allow one JUnit testcase to test a singleton class with more that one
initialization params is to use a custom classloader to load your singleton; every test-
method needs to instantiate a new TestClassLoader instance (a class that extends
the jdk ClassLoader). I did it like this:
public class TestClassLoader extends ClassLoader
{
public Class findClass(String name) throws ClassNotFoundException
{
byte[] b = loadClassData(name);
return defineClass(name, b, 0, b.length);
}

private byte[] loadClassData(String name)


throws ClassNotFoundException
{
InputStream stream =
getClass().getClassLoader()
.getResourceAsStream(name + ".class");

String path = null;


try
{
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
int i;
while ((i = stream.read()) != -1)
{
bOut.write(i);
}
return bOut.toByteArray();
}
catch (FileNotFoundException ex)
{
throw new ClassNotFoundException(
"Class " + name + " could not be found from " + path,
ex);
}
catch (IOException ex)
{
throw new ClassNotFoundException(
"Class " + name + " could not be found", ex);
}
}
}
Comments and alternative answers

Unfortunatelly I did not understand the comment.


Author: Sergey Opanasets (http://www.jguru.com/guru/viewbio.jsp?EID=392845),
May 23, 2002
What difference it makes if you use custom class loader versus standard class loader?

Thank you in advance.

Re: Unfortunatelly I did not understand the comment.


Author: James Radvan (http://www.jguru.com/guru/viewbio.jsp?EID=873937),
May 12, 2004
You can always run it as a Cactus test instead, which gets around the classloading
problem.

Re: Unfortunatelly I did not understand the comment.


Author: Janne Nykänen (http://www.jguru.com/guru/viewbio.jsp?EID=874437),
Dec 22, 2004
In case you don't wanna use cactus; by using the custom classloader you can
unload the class (by throwing away the classloader used to load the singleton
class). So you instantiate a new TestClassLoader for each test.

Multiple params with html:link tag?

How to code my Struts html:link tag such that I can apply multiple dynamic
parameters?

For example, I want to achieve the following:

<a
href="/DeptInfo/do/ViewDept?setID=<%=deptForm.getSetID()%>&<%=deptForm.
getDeptID%>">

But I only know this much in terms of coding it with a Struts tags:
<html:link forward="ViewDept" paramName="deptForm"
paramProperty="setID" paramId="setID" />

How do I get the deptID param into this tag as well? (And by the way, is my
syntax above correct for the html:link tag??)

Thanks
Location: http://www.jguru.com/faq/view.jsp?EID=877089
Created: May 13, 2002
Author: Nguyen van Tin (http://www.jguru.com/guru/viewbio.jsp?EID=761500)
Question originally posed by John Crossman
(http://www.jguru.com/guru/viewbio.jsp?EID=12222
If you want to add multipe params in the html:link, you have to save these params
into a Map object. The Map's key are paramid and Map's value is paramProperty. And
then you can do : <html:link page="ViewDept" name="xxx"/> with xxx is The name
of a JSP bean that contains a Map representing the query parameters. You can see in
Struts HTML tags for detail. Hope that can solve your problem. good luck, NVT
Comments and alternative answers

create a HashMap array and use name attribute of


html:link tag
Author: sathish kumar
(http://www.jguru.com/guru/viewbio.jsp?EID=884972), May
20, 2002
hi i have a solution to ur problem.For eg u have a company
list which needs to be passed as dynamic params. U can
create an array of HashMap, one HashMap for each
company.Each HashMap containing 2 key value pairs(one
for comapnyId, other for companyName). for instance
companyInfo is ur HashMap
companyInfo.put(companyId,"90");
companyInfo.put(companyName,"Cognizant"); add this to
the hashmap array, put the hashmap array in session In ur jsp
(companyList --> hashmap array get from session)
<logic:iterate name="companyList" id="company"> (ur
logic:iterate will have current hashmap )

<html:link
forward="viewCompany"
name="company">
<bean:write
name="company"
property="name"/>
</html:link>
</logic:iterate> Hope this
solves ur problem.I too
had the same problem
and i found it by
hardway(spent 3hrs).
regards sathish

Re: create a HashMap array and use name attribute of html:link tag
Author: aiuto lee (http://www.jguru.com/guru/viewbio.jsp?EID=935029), Jul 2,
2002
I sovled the problem.
I had spent a lot of time on sovling this problem.
I except you not to spend your time for this problem.

enjoy your life... :-)

------------------
One of Solutions |
========================================================
<html:html>
....

<bean:parameter id="param1" name="param1" value="0"/>

<%

java.util.HashMap params = new java.util.HashMap();


params.put("param1", param1);
params.put("param2","param2Value");
pageContext.setAttribute("paramsName", params);
%>

<html:link page="/show.do" name="paramsName" scope="page"


>show.jsp</html:link>

.....
.....
</html:html>
========================================================

-fine-

Re[2]: create a HashMap array and use name attribute of html:link tag
Author: Jim Downing (http://www.jguru.com/guru/viewbio.jsp?EID=975661),
Aug 4, 2002

Is there an elegant way of doing this without scriptlets?

Something like: -

<bean:define type="java.util.Map" id="tempParams>


<param id="type" value="cabbages"/>
<param id="sort" value="firmness"/>
</bean:define>
<html:link page="/blah" paramName="tempParams">
Find the firmest cabbages
</html:link>

jim

Re[3]: create a HashMap array and use name attribute of html:link


tag
Author: aiuto lee (http://www.jguru.com/guru/viewbio.jsp?EID=935029),
Aug 4, 2002
Body is supposed to be empty for bean:define. I know that it is not
supported to use <param> tage inside <bean:define> tag. I can not find this
way in Struts's manual. Where do you get this inforamtion? -fine-

Re[4]: create a HashMap array and use name attribute of html:link


tag
Author: Jim Downing
(http://www.jguru.com/guru/viewbio.jsp?EID=975661), Aug 5, 2002

Sorry, I wasn't clear. The code snippet I wrote was a made up example
of what I was hoping existed. I can't find anything sensible to replace
your scriptlet.

jim

How to Create a Map object using <bean:define> tag or any


other tag in Struts
Author: praveen kumar
(http://www.jguru.com/guru/viewbio.jsp?EID=992887), Sep 2,
2002
This is my code snipplet,
<bean:define id="param1" name="ele" property="score"/>
<bean:define id="param2" name="ele" property="color" />
<%
java.util.HashMap params = new java.util.HashMap();
params.put("regno", param1);
params.put("regname", param2);
pageContext.setAttribute("paramsName", params);
%>

<html:link styleClass="link" page="/xAction.do?


action=x" name="paramsName"/>
I dont want to use the scriptlet. I want to put these two
beans(param1 and param2) in another bean collection using struts
tags, so that I could use the created bean name in my link. Could
anyone pls help me in providing a solution for this.
thanks
Praveen

Re[2]: create a HashMap array and use name attribute of html:link tag
Author: Phil Spanninger
(http://www.jguru.com/guru/viewbio.jsp?EID=1106267), Aug 4, 2003
Thanks for the tip! This worked great, but now i need to know how to actually
pull those values out of the querystring in your Action class? I know that
typically you can use the "getAttribute" method off the request, but i am using
an ICL package that wraps the request into a different object and will not grant
me access. Do you have any suggestions other than pulling this from the
request object? Ie. could i somehow map each parameter in my mapping
method within the Action class (the one being called)? Please help!

Re[2]: create a HashMap array and use name attribute of html:link tag
Author: w yj (http://www.jguru.com/guru/viewbio.jsp?EID=1120205), Oct 8,
2003
thanks for your code. But I am still bit confusing, hope you can spare some
time for me.

My problem is I got a results.jsp page which contains search results including


three dynamic parameters tableName,batchId and recordId. So I 'll have

<% java.util.HashMap rawSourceMap=new java.util.HashMap();


rawSourceMap.put("tableName", tableNameValue);
rawSourceMap.put("batchId", batchIdValue);
rawSourceMap.put("recordId", recordIdValue);
pageContext.setAttribute("rsMap",rawSourceMap);%>

<html:link forward="CheckRawSource.do" name="rsMap"/>

My question is, depends on what tableName I got, I should direct to different


jsp pages. I have tableA, tableB, tableC,etc, all tables have different fields
name, so I 'll have tableA.jsp, tableB.jsp, tableC.jsp to show different raw
sources. How can I do this? How do I write this in my struts-config file?

Thanks,

WYJ
Re[3]: create a HashMap array and use name attribute of html:link
tag
Author: wu haixing
(http://www.jguru.com/guru/viewbio.jsp?EID=1148860), Feb 24, 2004
I had solved my problem.I want to set two request parameters value by
objects had stored in session,but is there has better solution?thanks a lot
1.use <bean:define> get values from object stored in session.
2.declare HashMap instance params to store request params
3.add to <html:link> with 'name' attribute.
as follow:
<bean:define id="category" name="product"
property="categoryId"/>
<bean:define id="keywords" name="item"
property="attribute4"/>
<%
java.util.HashMap params = new java.util.HashMap();
params.put("category",category);
params.put("keywords",keywords);
pageContext.setAttribute("paramsName", params);
%>

<html:link name="paramsName" scope="page"


page="/searchItems.do">
<bean:write name="item" property="attribute4" />
</html:link>

Re[4]: create a HashMap array and use name attribute of html:link


tag
Author: Kris M (http://www.jguru.com/guru/viewbio.jsp?EID=78001),
Feb 27, 2004
Hi
Someone had the same problem and wrote a tag library to
handle this problem. Where you can pass multiple
parameters through a link. The link is
http://sourceforge.net/project/showfiles.php?group_id=47722
get the sources and take a look at the LinkTag and
LinkParamTag

roller\web\website\edit-pages.jsp has the code that


utlizes this tag.

If you end up using this tag, may be you can retain the
copy right, after all you have to give the credit to the
people who wrote it.. hope this will solve your problem..
!! Reuse of Code !! Always, Every Time, Give Credit, It makes people
Happy !! enjoy kris

Re[5]: create a HashMap array and use name attribute of


html:link tag
Author: vasanth tatta
(http://www.jguru.com/guru/viewbio.jsp?EID=1166824), Jun 23,
2004
hi,

with respect to the Maps

I do not want to define the bean or create the map in


the page Instead I thought this would work. Except for
it didn't.

Please point me in right direction.

what I have done is written a public Map getParams()


method that returns my parameters in a map.

and this is in the FormBean but, when i try to access


the params in the link as
<html:link action="/something.do" name="params" />

I get an error

Cannot find bean params in any scope

The bean is in the session and can get all the other
stuff from that bean in the jsp except this map?

I would appreciate your suggestions.

regards.

Re[6]: create a HashMap array and use name attribute of


html:link tag
Author: Pratik Das
(http://www.jguru.com/guru/viewbio.jsp?EID=1188134), Aug 4,
2004
You need to have either Map by the name "params" or
a bean by the name "params" in any scope with a
property of type Map.

In your case:

1. define a property of type Map in your formbean


and populate the map with key value pairs in your
formAction and put it in request or session
scope.The key will appear as parameter name and key
value will appear as parameter value.
In your jsp use the following code:

<html:link page="/flightDetail.do" name="orionForm"


property="paramList"><bean:write name="orionList"
property="c64" /></html:link>

where orionForm is the name of the formBean having


a property named paramList of type Map. Make sure
the map is not null and populated. The parameters
will not appear without giving any errors.

Using Map instead of String properties with ActionForm. How do you use a
Map object with ActionForm with Struts 1.1-b1?

Mr. Husted, in a message posted on the FAQS you said:

In Struts 1.1 beta, a Map can be used instead of individual properties on an


ActionForm.
Could you please elaborate?

I would like to define a common ActionForm that accepts a Map which


would just include the form elements and values. I would like to use this
ActionForm with reusable Actions that could be used across multiple forms
or JSPs. Is this possible with Struts?

Thanks.
Location: http://www.jguru.com/faq/view.jsp?EID=890992
Created: May 24, 2002
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by Kevin Turner
(http://www.jguru.com/guru/viewbio.jsp?EID=844420

Since 1.1b

private Map values = null;

public void setValues(Map values) {


this.values = values;
}
public Map getValues() {
return this.values;
}

public void setValue(String key, Object value) {


getValues().put(key,value);
}
public Object getValue(String key) {
return getValues().get(key);
}

...

<html:text property="value(name)"/>

HTH -Ted

Comments and alternative answers

To clarify further...
Author: Peter Hamlen (http://www.jguru.com/guru/viewbio.jsp?EID=924276), Jun
23, 2002

Since I spent a little bit of time trying to figure this out, I thought I would try to add
some clarification that I have since discovered...

The key to the ability to use "maps" in your Beans comes from the the class
org.apache.commons.beanutils.PropertyUtils. This very useful class extends
the syntax for accessing Bean properties to include 5 different methods:

• Simple - propertyName
• Nested - bean1.bean2.propertyName
• Indexed - propertyName[3]
• Mapped - property(key)
• Combined - you can combine the above

The best place to read about this is: the jakarta commons javadoc

So what this means is that, if you want to get away from writing getFoo, setFoo,
getBar, setBar, etc, you need to:

1. Create a JavaBean object that supports the "mapped" format from


org.apache.commons.beanutils.PropertyUtils. Specifically, it should
have a set method that takes a String and an object, and a get method that
takes a string and returns an object. For the example above, getValue and
setValue
2. Refer to properties by "value(keyName)". Basically, Struts will see the "()"
and realize this is a mapped bean, will take "keyName" as a key and pass it to
the method getValue

That's my best take on explaining this. Read the commons link, it will help a lot.

Re: To clarify further...


Author: rajani sarikonda (http://www.jguru.com/guru/viewbio.jsp?EID=933318), Jul 1, 2002
when i try this approach, i am getting the following error. Could you please help me in getting the
solution. Root cause of ServletException javax.servlet.jsp.JspException: No getter method for
property value(test) of bean org.apache.struts.taglib.html.BEAN at
org.apache.struts.util.RequestUtils.lookup(RequestUtils.java:227) at
org.apache.struts.taglib.html.BaseFieldTag.doStartTag(BaseFieldTag.java:220) at
jsp_servlet._ui._questionnaire._jspService(_questionnaire.java:209) at
weblogic.servlet.jsp.JspBase.service(JspBase.java:27) at
weblogic.servlet.internal.ServletStubImpl.invokeServlet(ServletStubImpl.java:213) at
weblogic.servlet.internal.WebAppServletContext.invokeServlet(WebAppServletContext.java:1265)
at weblogic.servlet.internal.ServletRequestImpl.execute(ServletRequestImpl.java:1622) at
weblogic.kernel.ExecuteThread.execute(ExecuteThread.java:137) at
weblogic.kernel.ExecuteThread.run(ExecuteThread.java:120)

Re[2]: To clarify further...


Author: Peter Hamlen (http://www.jguru.com/guru/viewbio.jsp?EID=924276),
Jul 1, 2002
Rajani, I might try the following:

1. Make sure you're running Struts 1.1 (or later) - this doesn't work on
Struts 1.0.2
2. Make sure you've defined the bean so that it has a method called '
public Object getValue(String key)' (as well as the setter method 'public
void setValue(String key, Object o)'
3. Make sure you include the "name='YourBeanNameHere'" in the
<HTML:Base> tag.
4. If that doesn't help, include the JSP snippet...

Re[3]: To clarify further...


Author: rajani sarikonda
(http://www.jguru.com/guru/viewbio.jsp?EID=933318), Jul 1, 2002
Hi, can you please elaborate the 3rd point(Make sure you include the
"name='YourBeanNameHere'" in the <HTML:Base> tag).
I have written the following code in actionform class,

private Map values = null; public void setValues(Map values) { this.values


= values; } public Map getValues() { return this.values; } public void
setValue(String key, Object value) { getValues().put(key,value); } public
Object getValue(String key) { return getValues().get(key); }

and accessing from jsp like this. <html:text property="value(name)"/>


thanks

Re[4]: To clarify further...


Author: Peter Hamlen
(http://www.jguru.com/guru/viewbio.jsp?EID=924276), Jul 1, 2002
My HTML tag usually looks like this:
<html:text name="appForm" property="value(name)"/>

You need to specify the name of the bean in the HTML:text call . Thus,
I would change your code to:
<html:text name="registrationForm"
property="value(name)"/>
(assuming that the name of your form bean is "registrationForm" -Peter

Re[4]: To clarify further...


Author: Ivan Filipino
(http://www.jguru.com/guru/viewbio.jsp?EID=929600), Jul 3, 2002
I think you forgot to create a HashMap object. Try adding this code in
your ActionForm object.
public void reset(ActionMapping mapping,
HttpServletRequest request) {
values = new HashMap();
}

Re[5]: To clarify further...


Author: Susan Weber
(http://www.jguru.com/guru/viewbio.jsp?EID=1005214), Sep 27,
2002

here is how I made it work. this is /test.jsp:

<%@ taglib uri="/WEB-INF/struts-html.tld"


prefix="html" %>
<jsp:useBean id="dbean" scope="session"
class="MapBackedActionForm"/>
<html:form action="/test">
<html:text name="dbean" property="value(name)"/>
</html:form>

here are the snippets from struts-config.xml

<form-bean
name="testForm"
type="MapBackedActionForm"/>
<action
path="/test"
type="org.apache.struts.ForwardAction"
name="testForm"/>

MapBackedActionForm extends ActionForm and has the structure


described in the above thread, with generic getter and setter and a
reset method that initializes the hashmap.

I am still slightly boggled by the fact that I had to reference


MapBackedActionForm in two places, in the .jsp source and in the
form-bean descriptor, but my grasp of struts is still quite shallow. If
someone can post a cleaner example, that would be a useful thing
I'm sure.

Re[3]: To clarify further...


Author: Ping Long (http://www.jguru.com/guru/viewbio.jsp?EID=799119),
Aug 6, 2002
Hi,Peter,
Any ideas how to use map inside <logic:iterate></<logic:iterate>?
Example code:
<logic:iterate id="desc" collection="<%=(Collection)
HashMapForm.getList()%>" type="java.lang.String">
<html:text property="value(???)"/>
</logic:iterate>

Thanks. -Ping

Re[4]: To clarify further...


Author: neal ravindran
(http://www.jguru.com/guru/viewbio.jsp?EID=17737), Dec 20, 2002
Did you find an answer for this? If so kindly share.

Re[4]: To clarify further...


Author: Brad Schneider
(http://www.jguru.com/guru/viewbio.jsp?EID=1089492), Jun 1, 2003
I got the following to work:
<logic:iterate name="listRightsForm" property="rights"
id="RightsView">

<bean:define name="RightsView" property="rightname"


id="rname" type="java.lang.String"/>

<% String cbprop = "value(" + rname + ")"; %>


<html:checkbox name="listRightsForm" property="<%= cbprop
%>"/>

</logic:iterate>

Re[2]: To clarify further...


Author: java maniac (http://www.jguru.com/guru/viewbio.jsp?EID=1059488),
Feb 25, 2003
i got the same problem but when i changed the jsp to values() rather than
value() it worked.

Re[2]: To clarify further...


Author: Thomas Poulet
(http://www.jguru.com/guru/viewbio.jsp?EID=1101382), Jul 15, 2003
Hi Rajani,

I am exactly in your situation,(one year later,) and I was wondering if you


finally found out the cause of your problem...

I read a lot of useful things on different forums (I am new in Struts), but


unfortunately I still have this : "javax.servlet.ServletException: No getter
method for property value(test) of bean org.apache.struts.taglib.html.BEAN".

Would you have any idea to help me ? Thanks.

Thomas.

Re[3]: To clarify further...


Author: Tony Cao
(http://www.jguru.com/guru/viewbio.jsp?EID=1182538), Jun 29, 2004
getter and setter functions are case sensitive.

For example: // variables String userid; String password;

// getter setter public String getUserid() { return this.userid; }

public void setUserid(String u) { this.userid = u; }

public String getPassword() { return this.password; }

public void setPassword(String p) { this.password = p; }

Hope this help.


Re[4]: To clarify further...
Author: Tony Cao
(http://www.jguru.com/guru/viewbio.jsp?EID=1182538), Jun 29, 2004
getter and setter functions are case sensitive.
For example:
// variables
String userid; String password;

// getter setter
public String getUserid() { return this.userid; }

public void setUserid(String u) { this.userid = u; }

public String getPassword() { return this.password; }

public void setPassword(String p) { this.password = p; }

Hope this help.

Re[3]: To clarify further...


Author: Rick Herrick
(http://www.jguru.com/guru/viewbio.jsp?EID=1195078), Aug 25, 2004
Hey, Thomas! I've been struggling with this one all day and finally got it
figured out. You can check out some sample code I wrote up that
demonstrates the solution. Note that this works with the standard Struts 1.1
release (at one point I thought I needed to upgrade the commons-
beanutils.jar, but I didn't).

Re[4]: To clarify further...


Author: grace goona
(http://www.jguru.com/guru/viewbio.jsp?EID=1203569), Oct 5, 2004
where is the sample code you wrote up?

Re[5]: To clarify further...


Author: yayo yayez
(http://www.jguru.com/guru/viewbio.jsp?EID=1222082), Jan 19,
2005
I use this to avoid the use of scriplets:

protected Map cursos = new HashMap();

public Map getCursos(){return new HashMap(cursos);}

c;

...
<!-- inside the iterate of the property 'cursos' -->

<html-el:hidden
property="indexedCurso('${pageScope.i}').cursoId" />

And it workz!!

Struts Tip #1 - Use an ImageButtonBean to represent an image button.


Location: http://www.jguru.com/faq/view.jsp?EID=893423
Created: May 27, 2002 Modified: 2002-09-06 04:52:16.755
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

An endless source of aggravation is the HTML input image element. The specification
says that browsers should treat this control like an image map. Unlike other buttons,
it does not submit a string representing the button's label, it submits the X and Y
coordinates. If you look at the HTTP post for an image button, you'll see it looks
something like this

myImageButton.x=200
myImageButton.y=300

For most other controls, a Struts developer can create a simple String property to
represent the element. This clearly won't work with an image button, because it
submits two "dotted" properties instead of a simple "name=value" entry like other
elements.

Happily, Struts allows an ActionForm to contain, or nest, other JavaBeans, and will
automatically populate the beans using the same syntax as the image element.
(What a co-inky-dink!)

To represent an image input element in your ActionForm, say what you mean, and
use an ImageButtonBean to capture the X and Y parameters.

public final class ImageButtonBean extends Object {

private String x = null;


private String y = null;

public String getX() {


return (this.x);
}

public void setX(String x) {


this.x = x;
}
public String getY() {
return (this.y);
}

public void setY(String y) {


this.y = y;
}

public boolean isSelected() {


return ((x!=null) || (y!=null));
}

} // End ImageButtonBean

Note that we've included a helper method on this bean, isSelected(). This just
returns true if either the x or y property is not null. If both are still null, then
isSelected() returns false.

Here's how you could declare two ImageButtonBeans on an ActionForm.

// ..

private ImageButtonBean logonButton = new ImageButtonBean();

public void setLogonButton(ImageButtonBean button) {


this.logonButton = button;
}

public ImageButtonBean getLogonButton() {


return this.logonButton;
}

private ImageButtonBean cancelButton = new ImageButtonBean();

public void setCancelButton(ImageButtonBean button) {


this.cancelButton = button;
}

public ImageButtonBean getCancelButton() {


return this.cancelButton;
}

// ...

The next question will be "OK, which button did they push?", so let's define another
helper method on the ActionForm to tell us.

public String getSelected() {

if (getLogonButton().isSelected()) {
return Constants.LOGON;
}
if (getCancelButton().isSelected()) {
return Constants.CANCEL;
}

return null; // nobody home


}

In an Action, determining which button is pressed is then a simple matter of asking


the form what was selected.

String selected = ((myForm) form).getSelected();

if (Constants.CANCEL.equals(selected)) ...

Of course selected doesn't need to be a String; it could be an int, a custom type to


represent your API functions, or even the name of another method for use with a
DispatchAction.

Using "API helper methods" on ActionForms, as we did with getSelected(), is a very


useful technique. We'll use it again in Tip #2, when we discuss the standard Dispatch
Actions.

HTH, Ted.

---

Struts Tips are excerpts from the book Java Web Development with Struts. The tips
released twice weekly on the MVC-Programmers List. To subscribe, visit BaseBean
Engineering.

About Ted. Ted Husted is an active Struts Committer and co-author of Java Web
Development with Struts and Professional JSP Site Design. Ted also moderates the
Struts mailing list and the JGuru Struts FAQ.

Copyright Ted Husted 2002. All rights reserved.

---

MVC-Programmers mailing list


MVC-Programmers@basebeans.com
http://www.basebeans.com:8081/mailman/listinfo/mvc-programmers

Comments and alternative answers

multiple image buttons


Author: joy joy (http://www.jguru.com/guru/viewbio.jsp?EID=1027752), Nov 19,
2002
Suppose I have two image buttons in a form
<html:image srcKey="image.next" align="center"/>

<html:image srcKey="image.cancel" align="center"/>

and define a bean class as you defined. I am wondering how these two image button
bean objects can be instantiated.
Any reply are appreciated.
Joy

Make sure "value" isn't set


Author: Michael Rush (http://www.jguru.com/guru/viewbio.jsp?EID=1140634), Jan
22, 2004

Make sure that within the html:image tag that "value" isn't specified. If so, some
browsers (Firebird is an example) submit *3* params instead of 2, so you end up with
request parameters like:

loginButton: Login
loginButton.y: 9
loginButton.x: 15

When that happens, BeanUtils.populate() will spit out the following:


java.lang.IllegalArgumentException: argument type mismatch

If omitting the value isn't possible, the following workaround works:

original:

public void setCancelButton(ImageButtonBean cancelButton) {


this.cancelButton = cancelButton;
}

new:

public void setCancelButton(Object cancelButton) {


if (cancelButton instanceof String) return;
this.cancelButton = (ImageButtonBean) cancelButton;
}

How to reset the submit action in Action


Author: Anuj Upadhyay (http://www.jguru.com/guru/viewbio.jsp?EID=243531), Mar
11, 2004

I have implemented the image button as defined and all was working fine till I had to
process a now UI action which I define as a separation action in the struts-config file.
At first i get the button click, no UI event in my case, I forward the call to the relevant
action class.

i.e. in the /mainAction mapping

if(form.getA().pressed()){
//mapping is of type ActionMapping
return (mapping.findForward("resetDate"));
}

The call get forwaded to the action I defined for /resetDate action mapping.

now in resetDate action i do some porcessing and finally forward back the to
/mainAction (definded in the struts-config).

return (mapping.findForward("mainAction"));
I may be doing something wrong but I want to get back to my calling action.

The called does get back to the /mainAction but the implementation finds that button
A was pressed and then i run into a never ending look.

I have tried various ways to set the X & Y values to null but that does not hely either.
Can you suggest of a way to do this. One way I found was to have the processing I
was doing in /resetDate in the /mainAction, but I would like to have this
implementation separate as a separate action mapping.

What are your comments on the same.


Thanks,
Anuj

Struts Tip #2 - Use DispatchAction to organize related operations


Location: http://www.jguru.com/faq/view.jsp?EID=897290
Created: May 30, 2002 Modified: 2002-09-06 04:51:29.193
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

Any software application is defined by the things it can do for you. In a Struts Web
application, the things an application does is usually defined by its action-mapping
elements. An action-mapping is designed to be the target of an HTML form, and is
often used with hyperlinks as well.

Each action-mapping can specify a Struts Action class as its handler. In larger
applications, developers can find themselves managing dozens or even hundreds of
Action classes.

In practice, many of these Action classes handle related operations, often evidenced
by their name. A package might include separate RegCreate, RegSave, and
RegDelete Actions, which just perform different operations on the same RegBean
object. Since all of these operations are usually handled by the same JSP page, it
would be handy to also have them handled by the same Struts Action.

A very simple way to do this is to have the submit button modify a field in the form
which indicates which operation to perform.

<html:hidden property="dispatch" value="error"/>


<SCRIPT>function set(target)
{document.forms[0].dispatch.value=target;}</SCRIPT>
<html:submit onclick="set('save');">SAVE</html:submit>
<html:submit onclick="set('create');">SAVE AS NEW</html:submitl>
<html:submit onclick="set('delete);">DELETE</html:submit>

Then, in the Action you can setup different methods to handle the different
operations, and branch to one or the other depending on which value is passed in the
dispatch field.

String dispatch = myForm.getDispatch();


if ("create".equals(dispatch)) { ...
if ("save".equals(dispatch)) { ...

The Struts Dispatch Action [org.apache.struts.actions] is designed to do exactly the


same thing, but without messy branching logic. The base perform method will check
a dispatch field for you, and invoke the indicated method. The only catch is that the
dispatch methods must use the same signature as perform. This is a very modest
requirement, since in practice you usually end up doing that anyway.

To convert an Action that was switching on a dispatch field to a DispatchAction, you


simply need to create methods like this

public ActionForward create(


ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException { ...

public ActionForward save(


ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException { ...

Cool. But do you have to use a property named dispatch? No, you don't. The only
other step is to specify the name of of the dispatch property as the "parameter"
property of the action-mapping. So a mapping for our example might look like this:

<action
path="/reg/dispatch"
type="app.reg.RegDispatch"
name="regForm"
scope="request"
validate="true"
parameter="dispatch"/>

If you wanted to use the property "o" instead, as in o=create, you would change the
mapping to

<action
path="/reg/dispatch"
type="app.reg.RegDispatch"
name="regForm"
scope="request"
validate="true"
parameter="o"/>

Again, very cool. But why use a JavaScript button in the first place? Why not use
several buttons named "dispatch" and use a different value for each?

You can, but the value of the button is also its label. This means if the page
designers want to label the button something different, they have to coordinate the
Action programmer. Localization becomes virtualy impossible.

If you prefer not to use JavaScript buttons, you can use the DispatchLookup Action
instead. This works much like the DispatchAction, but requires more setup. We'll
explore the DispatchLookup Action in Tip #3.

HTH, Ted.

---

Struts Tips are excerpts from the book Java Web Development with Struts. The tips
released twice weekly on the MVC-Programmers List. To subscribe, visit BaseBean
Engineering.

About Ted. Ted Husted is an active Struts Committer and co-author of Java Web
Development with Struts and Professional JSP Site Design. Ted also moderates the
Struts mailing list and the JGuru Struts FAQ.

Copyright Ted Husted 2002. All rights reserved.

---

MVC-Programmers mailing list


MVC-Programmers@basebeans.com
http://www.basebeans.com:8081/mailman/listinfo/mvc-programmers

Comments and alternative answers

How do we validate the errors?


Author: Asha Augustine (http://www.jguru.com/guru/viewbio.jsp?EID=1156829),
Mar 23, 2004
Hi Ted. How do we validate the errors when using DispatchAction using validator
framework, if the submitting page and resultting page are same, but with different
argument?

For example, if I submit from /login.do?page=page1 and the action is


/login.do?page=page2. How do I write the action in Struts config ?

input vs. buttons


Author: Mark Diggory (http://www.jguru.com/guru/viewbio.jsp?EID=1180720), Jun
22, 2004
Well, the good news is that "button" tags in xhtml support the button value and its
presented text being quite different so even this is possible

<button name="dispatch" value="doIt">My Button</button>

This makes using the submit button all the more easier.

-Mark

Re: input vs. buttons


Author: Binay Warrier (http://www.jguru.com/guru/viewbio.jsp?EID=1181171),
Jun 27, 2004
But then how will "My Button" be able to behave like a submit button? Isnt it
necc. that it has to be of type input? so that inside the action, i can get the "value"
attribute for the button name. I am a newbie to this, so I dunno if I am going
wrong here...

Struts Tip #3 - Use LookupDispatchAction for a JavaScript-free dispatch


Location: http://www.jguru.com/faq/view.jsp?EID=900642
Created: Jun 3, 2002 Modified: 2002-09-06 04:50:22.724
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

Many forms can be put to multiple uses. The fields we need to create a record are
usually the same fields we use to update a record. Likewise, the same page can
usually used to identify a record to delete, copy, or update a record.

A DispatchAction (see Tip #2) is a convenient way to collect related operations like
this into a single Struts Action class. A field in the request identifies the operation,
and so all the developer has to do is get the right value into the field. The simplest
way to do this is to label the buttons for the operation, and give each button the
same name. But that ties the presentation label to the business operation and
confounds localization.
As an alternative, most developers use a JavaScript attached to the button to update
the dispatch field, which in practice works quite well. If JavaScript is not enabled, the
submit fails gracefully, and in practice most applications do rely JavaScript for
essential operations.

If JavaScript is not an option, another good alternative is the LookupDispatchAction


[org.apache.struts.actions.LookupDispatchAction]. This object is a little more
work to setup that the original DispatchAction, but lets you use this technique
without using JavaScript as a crutch.

As with the DispatchAction, the first step is to indicate the name of the dispatch
parameter in the action-mapping element. In this case the parameter will the name
given to each of the buttons, rather than a hidden field. Let's just call our buttons
"submit", which is the default name the html:submit tag will use.

<action path="/test"
type="org.example.MyAction"
name="MyForm"
scope="request"
input="/test.jsp"
parameter="submit"/>

In our JSP, we can refer to the buttons in the usual way

<html:form action="/test">
<html:submit>
<bean:message key="button.add"/>
</html:submit>
<html:submit>
<bean:message key="button.delete"/>
</html:submit>
</html:form>

Later, when the user selects a button, the form will pass the submit parameter, along
with whatever message is Struts finds for "button.add" or "button.delete" in the
resource bundle. In a localized application, this message could vary by the user's
selected locale.

Using the conventional DispatchAction, this approach would problematic, since there
would have to a Java method named for each message, and not all the messages
might valid Java identifiers. This is where the magic of the LookupDispatchAction
comes into play.

When you create your LookupDispatchAction subclass, along with the methods for
the dispatch operations (see Tip #20) you must also implement a getKeyMethodMap
method. This is a "hotspot" that the LookupDispatchAction will call.

Here's an example of the methods you might declare in your subclass:

protected Map getKeyMethodMap(ActionMapping mapping,


ActionForm form,
HttpServletRequest request) {
Map map = new HashMap();
map.put("button.add", "add");
map.put("button.delete", "delete");
return map;
}

public ActionForward add(ActionMapping mapping,


ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
// do add
return mapping.findForward("success");
}

public ActionForward delete(ActionMapping mapping,


ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws IOException, ServletException {
// do delete
return mapping.findForward("success");
}

Internally, the base action will lookup the messages for button.add and
button.delete, and match those against the submit parameter. When it finds a match,
it will then use either "add" or "delete" to call the corresponding methods.

So while the LookupDispatchAction means adding an extra method to your Action, it


lets you skip putting a JavaScript in your form.

Both the DispatchAction and LookupDispatchAction are an excellent way to


streamline your Struts action classes, and group several related operations into a
single umbrella action.

So, how many dispatch actions do you need? Can you use a dispatch action to collect
everything into a single action?

Most often not. In practice, you can easily use one dispatch action for any forms that
share a common validation. Sharing a dispatch action between different form beans,
or form beans that are validated differently, can start to make things harder rather
than simpler. But the use of a dispatch action can easily half or quarter the number
of action classes in most Struts application.

HTH, Ted.

Credits. The LookupDispatchAction was originated by Erik Hatcher, one of Struts


many volunteer contributors. The examples used in this tip relied heavily on Erik's
documentation. (Yeah reuse! Yeah JavaDocs!)

-----
Struts Tips are released twice weekly on the MVC-Programmers List. To subscribe,
visit BaseBean Engineering.

Struts Tips are excerpts from the book Java Web Development with Struts. The tips
released twice weekly on the MVC-Programmers List. To subscribe, visit BaseBean
Engineering.

About Ted. Ted Husted is an active Struts Committer and co-author of Java Web
Development with Struts and Professional JSP Site Design. Ted also moderates the
Struts mailing list and the JGuru Struts FAQ.

Copyright Ted Husted 2002. All rights reserved.

---

MVC-Programmers mailing list


MVC-Programmers@basebeans.com
http://www.basebeans.com:8081/mailman/listinfo/mvc-programmers

Comments and alternative answers

LookUpDispatchAction and indexed buttons.


Author: Jaakko R (http://www.jguru.com/guru/viewbio.jsp?EID=1116356), Oct 7,
2003

I have a form that has 2 submit buttons / line, edit and delete. Form can have 0-n lines
(I'm iterating a collection called properties) so what would be the best way to submit
the form if I have to pass one value (property key for databaseconnection) and the
required action to perform the required operation.

<logic:iterate id="property" name="properties"/>

<!-- property.key & other info here (all indexed) -->

<html:button property="action" indexed="true">


<bean:message key="button.edit"/>
</html:button>

<html:button property="action" indexed="true">


<bean:message key="button.edit"/>
</html:button>
</logic:iterate>

Alternative to using LookupDispatchAction


Author: John Hughes (http://www.jguru.com/guru/viewbio.jsp?EID=1179286), Jun 16, 2004
LookupDispatchAction provides a lot of flexibility for multi-lingual applications but it is kind of
cumbersome in that you have to have to implement additional methods set up for each type of
"action" your form needs to take. Here is an alternative:
Add a property to hold the action in your ActionForm.
Insert code to compare your action property in your ActionForm to the same value in your
resource file and determine the path from there.

Example action mapping:


<action path="/test"
type="org.example.MyAction"
name="MyForm"
scope="request"
input="/test.jsp"/>
Example JSP block:
<html:form action="/test">
<html:submit>
<bean:message key="button.add"/>
</html:submit>
<html:submit>
<bean:message key="button.delete"/>
</html:submit>
</html:form>
Import MessageResources class in your Action:
import org.apache.struts.util.MessageResources;
Example Action execute method:
public ActionForward execute(ActionMapping map, ActionForm reqForm,
HttpServletRequest request, HttpServletResponse response){
MyForm form = (MyForm) reqForm;

//*************************************************************************
***
//Gets a specified 'key' value from the resource bundle based on the
current Locale.
//This comes in handy when needing to compare a button label to the same
'key'
// value when using a form with multiple submit buttons.
MessageResources resources = this.getResources(request);
String sAddAction = resources.getMessage(this.getLocale(request),
"button.add");
String sDeleteAction = resources.getMessage(this.getLocale(request),
"button.delete");
//*************************************************************************
***

if (form.getAction().equals(sAddAction)){
//pass control to the proper business logic method for the add action
}
else if (form.getAction().equals(sDeleteAction)){
//pass control to the proper business logic method for the delete action
}

return map.findForward("success");
}
Why we chose this particular technique:
We wanted to keep our "controller" layer as light as possible. Because of this all of our business
logic is farmed out to EJBs. So, each action method would have been indentical except for a few
lines of code. We chose this technique to simplify our code rather than going with the
LookupDispatchAction.
Re: Alternative to using LookupDispatchAction
Author: vijai kanth (http://www.jguru.com/guru/viewbio.jsp?EID=1228316), Feb
21, 2005
i have tryed this technique but i get an error message of "cannot find symbol of
getAcion()" what can i do

Correction to: Alternative to using LookupDispatchAction


Author: John Hughes (http://www.jguru.com/guru/viewbio.jsp?EID=1179286), Jun
16, 2004
JSP code for the example should be:
<html:form action="/test">
<html:submit property="action">
<bean:message key="button.add"/>
</html:submit>
<html:submit property="action">
<bean:message key="button.delete"/>
</html:submit>
</html:form>

Struts Tip #4 - Formatting output with MessageResources


Location: http://www.jguru.com/faq/view.jsp?EID=915891
Created: Jun 17, 2002 Modified: 2002-11-09 19:41:09.511
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

A common requirement of the presentation layer is to format information in a


human-friendly way. While a numeral rendered as 1000000 works well for the
software, most humans can't turn that data into information at a glance. Humans
expect a numeral to be rendered as 1,000,000 - which they can interpret at a glance
to be the value one million.

At least to Americans.

People in other countries might find the name rather strange, since it includes two
decimal points, or what an American would render as 1.000.000.

Since many Struts applications are localized, this are important issues. When a page
in a Struts application renderes a number, or a date, or a percentage, it should be
able to do so according to each user's locale.

Struts already has localized messaging built-in, which most developers use for error
messages, prompts, and field label names. A Struts applications refers to messages
like this using a symbolic key, which is used to retrieve the actual messages from the
Struts application resource bundle. The messages can also be used as templates,
and the application can pass custom values to them at runtime. Often, there is a
default template for an entire class of message, and the field name or other value is
merged into the static text at runtime. Each locale can have it's own resource
properties file, which
Now, it's important to note that Struts didn't invent any of this. Resource bundles,
message templates, locales, and the rest of it are all part of the Java
internationalization framework. Struts makes Java i18n an intregal part of its own
framework, and provides support classes making it easier to use. But the core
functionality is provided by the Java internationalization framework.

Including the abilty to apply formatting to a value a runtime.

Most message templates are created by just indicating the placeholder, like

ordering.authorized.range.staff=Staff is only authorized to requisition


supplies that cost less than ${0}

It then becomes the application's responsiblility to supply whatever string is needed


to replace {0}, which will be inserted into the message template, as-is.

However, you can also pass more than one parameter as the placeholder, and also
include one of the standard message format classes: number, currency, percent -
along with a default mask. This means you can just as easily render the template as

ordering.authorized.range.staff=Staff is only authorized to requisition


supplies that cost less than {0,currency}

which will insert the appropriate thousands-delimter or decimal-separator for the


user's locale. This example would also insert the monetary symbol for the user's
country. If everything should be expressed in a single currency, then you'd use
number instead

ordering.authorized.range.staff=Staff is only authorized to requisition


supplies that cost less than ${0,number} USD

The same technique can be applied to dates and percentages. See the Java
Internationalization Tutorial's page on the MessageFormat class for more

While the Struts application resource bundle is most often used when generating
error messages, the <bean:message> tag can be used to access message templates
throughout your application, and pass the replacement parameters at runtime to
generate a customized display.

Here's the same example message coded for <bean:message>

<bean:message key="ordering.authorized.range.staff" arg0='<%=


config.getStaffAuthAmnt() %>'/>

where there is a bean in some scope named "config" that can return the amount in
question.

HTH, Ted.

-----
Struts Tips are excerpts from the book Java Web Development with Struts. The tips
released twice weekly on the MVC-Programmers List. To subscribe, visit BaseBean
Engineering.

About Ted. Ted Husted is an active Struts Committer and co-author of Struts in
Action and Professional JSP Site Design. Ted also moderates the Struts mailing list
and the JGuru Struts FAQ.

Copyright Ted Husted 2002. All rights reserved.

---

MVC-Programmers mailing list


MVC-Programmers@basebeans.com
http://www.basebeans.com:8081/mailman/listinfo/mvc-programmers

Comments and alternative answers

How to format a Date, using this?


Author: Calle Sollander (http://www.jguru.com/guru/viewbio.jsp?EID=2642), Jul 5,
2002
Hello!
I'm abit new to struts so forgive me if this is stupid.
I want to show a Date diffrently in diffrent Locales so I put
departureDate=Depaturedate: {0,date,long} in my properties file.
Then I realized that the "bean:message" only takes Strings as arguments.
Can you explain how to format the Date?
Before reading this tip I had solved it by making my own customtag that handled the
formating.
Thanks in advance for any help!
Regards, Calle

Re: How to format a Date, using this?


Author: Erik Godding Boye
(http://www.jguru.com/guru/viewbio.jsp?EID=985651), Aug 20, 2002
It seems impossible to do this since the bean:message tag require String as
arguments.
I would would suggest the Struts people to change the type of the arguments to
Object (as expected by the MessageFormat class that is actually used from whitin
the Struts classes).
For now you could use the i18n taglib from Apache taglibs project - which uses
Object for argument.

Regards, Erik

Example doesn't work


Author: Jason Marshall (http://www.jguru.com/guru/viewbio.jsp?EID=1007649), Oct
3, 2002
When I run the number format example in this code, I get an error:
Cannot format given Object as a Number
The most likely conclusion from this is that number formatting doesn't actually work
in Struts 1.0. Is that correct?

I18N'd arguments
Author: Josh Marquart (http://www.jguru.com/guru/viewbio.jsp?EID=30693), Jan 16,
2004

Here's a strange conundrum.

I want to use

<bean:message key="my.message" arg0="x" />

where

my.message=This is my message and it is in {0}.

That works fine if I do:

<bean:message key="my.message" arg0="English" />

or

<% String aVar = "Spanish"; %>


<bean:message key="my.message" arg0="<%= aVar %>" />

But what if arg0 has to be I18N'd and I don't want to use scriptlets?

I can't do this, can I?

<bean:message key="my.message"><arg0><bean:message
key="my.language"/></arg0></bean:message>

Or do I have to rely on the fmt: tag?

Struts Tip #5 - Use coarse-grained ActionForms


Location: http://www.jguru.com/faq/view.jsp?EID=915895
Created: Jun 17, 2002 Modified: 2002-09-06 04:43:12.545
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

The biggest hassle for any Struts developer can maintaining the #@$!%
ActionForms. The ActionForm provides several important services to an application,
since it is

• a firewall,
• a buffer for the HTML controls, and
• a mutable transfer object.

As a firewall it keeps untrusted input from passing directly into your application. As a
field buffer, it stores new input so it can verified before it is passed to more trusting
parts of your application, As a mutable transfer object (fka value object), the
ActionForm provides an extensible container where data can collected and passed in
a batch to one or more business or resource layer objects.

But, in practice, you usually need a different form-bean for each HTML form in your
application. This makes it easy to store the data for each form under its own
attribute, and to fine-tune the validation for each form.

Hey -- what's that about form-beans? I thought we were talking about ActionForms?

This is an important distinction. Each HTML form typically needs its own form-bean,
but a form-bean is not an ActionForm. A form-bean identifies which ActionForm to
use, in the same way an action-mapping identifies which Action class to use. Many
Struts developers share Actions between action-mapping, but tend to forget that you
can share ActionForms between form-beans too.

While ActionForms are vital objects, they are not subtle. Typically, they are a pure
data-only JavaBean, with nothing but accessors and mutators. Occasionally, there is
a helper method to transform data from one type to another, but even those are a
simple wrappers around standard library functions. With the Struts-Validator, most
ActionForms don't even need to subclass validate(). All that's needed is to define a
formset for each form-bean, or attribute, that needs validation.

So, why bother with more than one ActionForm class? The form-bean determines the
runtime attribute name, and therefore the formset the Struts-Validator will use.
Neither the validator nor the autopopulation utilities care if there are more properties
a form than are used with a given request. And, null properties consume fewer
resources that instantiating yet another class. So why not just put all the
application's properties together in a single ActionForm?

Worst case, you can define a base ActionForm with all the properties you need, and
subclass to provide any custom validations. Meanwhile, by aggregating your
application's properties into a single ActionForm, several key benefits are realized.

• Better Manageability. Implementing ActionForms as fine-grained containers


results in a large number of objects in the application, many of which have
redundant properties. This consumes both system and developer resources,
and can negatively impact application performance and long-term
maintenance.
• Relationships are preserved. Most HTML forms represent, in part, a SQL
view, which includes properties from several different tables. If an ActionForm
contains properties for all the fields, any relationship can represented.
• Schema independance. When ActionForms are fine-grained, each
ActionForm usually represents a single row in a database. This ties the
presentation layer to the database schema, rather than to the greater
business model. When the schema changes, fine-grained ActionForm objects
may also need to changed. Coarse-grained ActionForms change less
frequently, since if a field is moved from one table to another, it will still
available the form. If a field is introduced or renamed, only one ActionForm
object needs to adjusted.

In a larger application being developed by a team, you may want more than one
ActionForm for the application (even if you don't "need" one). There may, for
example, be one ActionForm each each major segment of the application being
handled by a smaller group or pair of programmers within the team. The important
thing is to try and group together all the properties that will be used together, so that
they are not continually re-defined throughout several related classes. ActionForms
are objects too and can be subclassed like any other object.

So the next time you need an ActionForm to go with a new form-bean, think twice
before creating a new class. Maybe you already have one you can reuse.

HTH, Ted.

-----

For more about aggregate entities in J2EE applications, see <


http://developer.java.sun.com/developer/restricted/patterns/AggregateEntity.html >.

Struts Tips are released twice weekly on the MVC-Programmers List. To subscribe,
visit BaseBean Engineering.

Struts Tips are excerpts from the book Java Web Development with Struts. The tips
released twice weekly on the MVC-Programmers List. To subscribe, visit BaseBean
Engineering.

About Ted. Ted Husted is an active Struts Committer and co-author of Java Web
Development with Struts and Professional JSP Site Design. Ted also moderates the
Struts mailing list and the JGuru Struts FAQ.

Copyright Ted Husted 2002. All rights reserved.

---

MVC-Programmers mailing list


MVC-Programmers@basebeans.com
http://www.basebeans.com:8081/mailman/listinfo/mvc-programmers

Comments and alternative answers

Hassle
Author: Nick Pellow (http://www.jguru.com/guru/viewbio.jsp?EID=920830), Jun 20,
2002
"The biggest hassle for any Struts developer can maintaining the #@$!%
ActionForms."
Does this not sound alarm bells that ActionForms are just not ideal.

How 'bout an example?


Author: Daniel Kehoe (http://www.jguru.com/guru/viewbio.jsp?EID=940015), Jul 6,
2002
I like the concept but I'm not sure how to share one ActionForm between multiple
web pages. Usually you specify the ActionForm to instantiate when input comes from
a particular page:
<action path="/mypath"
type="someAction"
parameter="action"
scope="request"
name="someForm"
input="/somepage.jsp"
validate="false">
</action>
How does a page know what ActionForm to use? The <jsp:useBean> tag? Or Struts
<bean:define> tag? Sure it's a newbie question, but I'd like to see where in the elusive
struts documentation the proper practice is explained.

Re: How 'bout an example?


Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042), Sep
6, 2002
The name attribute in the snippet refers to a form-bean element that in turns
specifies the ActionForm class. The ActionForms tend to be used by more than
one mapping, and so they are encapsulated under their own block. By default, the
name is also used as the attribute name in the servlet context. So this saves
specifying a logical name more than once.
HTH, -Ted.

Struts Tip #6 - Use an array to capture multiple parameters


Location: http://www.jguru.com/faq/view.jsp?EID=915898
Created: Jun 17, 2002 Modified: 2002-09-06 04:42:13.652
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

In a perfect universe, our users would happily subscribe to the One True Workflow. In
every case, we could list some records, select a record to view or edit, and list some
records again. But in real life, users often want to do unreasonable things, like edit
17 records at once.

Usually, we'd already have a business procedure for saving one copy of the record.
Perhaps something like this

String key= form.getKey();


String category = form.getCategory();
db.updateCategory(new Integer(key),category);

A very simple way to convert this to "multiple use" would to do something like this:
String[] key = form.getKey();
String[] category = form.getCategory();
for (int i=0; i<category.length; i++) { db.updateCategory(new
Integer(key),category); }

Depending on what the db object did behind the scenes, and the scale of the
application, this code fragment could too simple to be efficient, but for many small
intranet applications, it could work just fine.

Of course, that still leaves the problem of where to get an array of keys and a
matching array of categories.

Happily, HTTP supports submitting multiple parameters of the same name, and
Struts will autopopulate a String array as easily as a single String. So, to represent
the "multi-use" business operation in an ActionForm, we can do this:

private String[] key= null;


public String[] getKey() { return this.key; }
public void setKey(String[] key) { this.key = key; }

private String[] category = null;


public String[] getCategory() { return this.category; }
public void setCategory(String[] category) { this.category = category; }

Which is just the single-record version but with String[] instead of String.

In the JavaServer Page, the only real trick is to refer to the iterate id in the html
form tags.

<TABLE><html:form action="/item/StoreCategory">
<logic:iterate name="RESULT" property="iterator" id="row">
<TR>
<TH>name</TH>
<TH>category</TH>
</TR>
<TR>
<TD><bean:write name="row" property="name"/></TD>
<TD><%-- REMEMBER TO SPECIFY THE ITERATE ID AS THE NAME --%>
<html:select name="row" property="category">
<html:option value="ART">Art</html:option>
<html:option value="AUT">Automotive</html:option>
<%-- ... --%>
</html:select>
<%-- REMEMBER TO SPECIFY THE ITERATE ID AS THE NAME --%>
<html:hidden name="row" property="key"/>
</TD>
</TR>
</logic:iterate>
<TR>
<TD colspan="2" align="right">
<html:submit/>
</TD>
</TR>
</html:form>
</TABLE>

Now when they submit the form, it will include several category=XYZ&key=123 pairs
in the request. Struts will convert the category and key entries into individual arrays,
and the arrays can be used with your business objects to make the appropriate
update.

HTH, Ted.

-----

Struts Tips are excerpts from the book Java Web Development with Struts. The tips
released twice weekly on the MVC-Programmers List. To subscribe, visit BaseBean
Engineering.

About Ted. Ted Husted is an active Struts Committer and co-author of Java Web
Development with Struts and Professional JSP Site Design. Ted also moderates the
Struts mailing list and the JGuru Struts FAQ.

Copyright Ted Husted 2002. All rights reserved.

---

MVC-Programmers mailing list


MVC-Programmers@basebeans.com
http://www.basebeans.com:8081/mailman/listinfo/mvc-programmers

Comments and alternative answers

iterator?!?
Author: Kevin Yuen (http://www.jguru.com/guru/viewbio.jsp?EID=352701), Jun 19,
2002
Thanks Ted for such a good Struts Tip!! I am in need for such solution! However, I do
not fully understand the solution mentioned in the article.

In the <logic:iterate>, you mentioned a property called "iterator" and the name
"RESULT", what are they? I cannot find them in other places in the article. Do you
mind to explain them in more details?

In particular, do we need to implement some kind of iterator here?

Thanks.

Re: iterator?!?
Author: deeje cooley (http://www.jguru.com/guru/viewbio.jsp?EID=931933), Jul
2, 2002
I am also appreciative of this tip, but am struggling to understand how to actually
implement it within my project. Any follow up would be most helpful! peace
deeje

Re: iterator?!?
Author: Yves Remels (http://www.jguru.com/guru/viewbio.jsp?EID=806386), Jul
3, 2002
As far as I understood, we have to define and populate a bean which has a
getIterator() method and contains attributes for all parameters needed. This
collection substitutes "RESULT" in example.
In this case the ActionForm is only used for posting and validating data and is not
used to retrieve the parameters into the jsp.
Y.R.

Using array to capture multiple parameters


Author: sameena tabassum (http://www.jguru.com/guru/viewbio.jsp?EID=920868),
Jun 20, 2002
Thanks for the tip you had mentioned.I require to have a multiple input fields with the
same name which is populated within a loop.Iam able to capture the values in a String
array,but when I get an error in the page I need to repopulate the screen with same
error values.In that case,Iam facing the problem like I only get reference of array
elements in the textfield.How can I populate the values back to the same screen with
error?? Thanks, Sameena.

Re: Using array to capture multiple parameters


Author: Ralph Brandes (http://www.jguru.com/guru/viewbio.jsp?EID=928554),
Jun 26, 2002
I have the same problem. Did you find a solution ? Thanks in advance
Ralph

Re: Using array to capture multiple parameters. My solution


Author: Ralph Brandes (http://www.jguru.com/guru/viewbio.jsp?EID=928554),
Jun 27, 2002
i found a solution :
Form :
private String[] owner = new String[100];

public String getOwner (int x) {


return owner[x];
}

public void setAbsetzHASBETRAG (int num, String owner) {


this.owner[num] = owner;
}

Form-Validation :
for (int i = 0; i < owner.length; i++) {
String errorFeld = "owner" + i;
...
errors.add(errorFeld, new
ActionError("error.input.format"));
...
}

Jsp :
<% int count = 0;%>

<logic:iterate name="RESULT" property="iterator" id="row">

<bean:write name="row" property="foo"/>

<html:text property='<%= "owner[" + count +"]" %>'


size="16" maxlength="16"/>

<html:errors property='<%= "owner" + count %>'/>

<% count++ ;%>

</logic:iterate>

Hope it helps. But if there is a better solution, i would be happy to see it.
Ralph

Re[2]: Using array to capture multiple parameters. My solution


Author: Carole L. (http://www.jguru.com/guru/viewbio.jsp?EID=994730), Sep
5, 2002
Ralph,

I have tried your solution (without the validation stuff) but I get an error when
I try to display my JSP:

Exception thrown by getter for property owner[0] of bean


org.apache.struts.taglib.html.BEAN

Did I miss something?

Generated ActionForm and JSPs


Author: gilles vandaele (http://www.jguru.com/guru/viewbio.jsp?EID=938970), Jul 9,
2002
Could you please explain the 'RESULT' and the 'iterator' you used in there:
logic:iterate name="RESULT" property="iterator" id="row"
How do I separate the values of the iteration and the values of the bean.
I need to capture the values of the bean in an array (generated properties), but the
default values and the layout atributes are from the Action servlet. The Action servlet
generate my jsp and the ActionForm is generic and capture the values of the bean into
an array.
Any further ideas?
Tx.

Re: Generated ActionForm and JSPs


Author: john Walsh (http://www.jguru.com/guru/viewbio.jsp?EID=948255), Jul
13, 2002
If anyone has a working example of how to create an updateable collection on a
web page I'd be very grateful!!! these examples here get me 90% of the way there
but as the other's have commented there seems to be some confusion as to what
the substitutions of variables would be...ie."result" and so forth. for instance I have
a database table with x records...I don't know how many....I can create an arraylist,
vector or whatever of the records...but how do you accesss them as an array from
the jsp page.... this example is soooo close but doesn't compile... Help!!! Thank
you very much John Walsh jwalsh@kelaroo.com Struts newbie....

Re[2]: Generated ActionForm and JSPs


Author: Judy Wang (http://www.jguru.com/guru/viewbio.jsp?EID=1020579),
Nov 2, 2002
I have same problem. In the actionform, I define a array of a class like:
TestData{ int id; String desc; } In the array: TestArray{ String userid;
TestData[] s; } I can write the array to jsp. But I can't read the form's array
from jsp.

here is a complete working example.


Author: Raj K (http://www.jguru.com/guru/viewbio.jsp?EID=1027421), Dec 19, 2002
I first invoke /rowsActionShow.do it displays the prepopulated values.
I change the displayed values and submit
the form you will see that the form bean
is getting updated with the new values I have print statements in the
RowsActionSave.java. HTH Thanks, Raj.
/////////// RowsForm.java ////////////////
package test;
import org.apache.struts.action.*;
import java.util.*;
public class RowsForm extends ActionForm {
private String[] rowId;
private String[] rowProperty1;
public String[] getRowId() {
return rowId;
}
public void setRowId(String[] rowId) {
this.rowId = rowId;
}
public String[] getRowProperty1() {
return rowProperty1;
}
public void setRowProperty1(String[] rowProperty1) {
this.rowProperty1 = rowProperty1;
}
public ArrayList getRows() {
ArrayList rows = new ArrayList();
final int size = rowId.length;
for (int i = 0; i < size; i++) {
RowForm row = new RowForm();
row.setRowId(rowId[i]);
row.setRowProperty1(rowProperty1[i]);
rows.add(row);
}
return rows;
}

public void populateForm(Vector rowData) {


final int size = rowData.size();
rowId = new String[size];
rowProperty1 = new String[size];
Enumeration enum = rowData.elements();
for (int i = 0; i < size; i++) {
RowForm element = (RowForm) enum.nextElement();
rowId[i] = String.valueOf(element.getRowId());
rowProperty1[i] = element.getRowProperty1();
}
}
}

///////////////// RowForm.java /////////////////////


package test;

import org.apache.struts.action.*;
import java.util.List;
import java.util.ArrayList;

public class RowForm extends ActionForm {

private String rowId;


private String rowProperty1;
public String getRowId() {
return rowId;
}
public void setRowId(String id) {
this.rowId = id;
}
public String getRowProperty1() {
return rowProperty1;
}
public void setRowProperty1(String property1) {
this.rowProperty1 = property1;
}
}

//////////////// RowsActionShow.java /////////////


package test;
import org.apache.struts.action.*;
import javax.servlet.http.*;
import java.lang.reflect.Method;
import java.util.*;

public class RowsActionShow extends Action {


public ActionForward perform(
ActionMapping mapping,ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws java.io.IOException,
Javax.servlet.ServletException {
RowsForm rowsForm = (RowsForm) form ;

Vector rowData = new Vector() ;


RowForm rf0 = new RowForm() ;
rf0.setRowId("1") ;
rf0.setRowProperty1("James") ;
rowData.add(rf0) ;
RowForm rf1 = new RowForm() ;
rf1.setRowId("2") ;
rf1.setRowProperty1("Peter") ;
rowData.add(rf1) ;
rowsForm.populateForm(rowData) ;
ActionForward result= mapping.findForward("rowspage");
return result;
}
}

//////////////// RowsActionSave.java /////////////


package test;
import org.apache.struts.action.*;
import javax.servlet.http.*;
import java.lang.reflect.Method;
import java.util.*;

public class RowsActionSave extends Action {

public ActionForward perform( ActionMapping mapping,


ActionForm form,
HttpServletRequest request, HttpServletResponse response)
throws java.io.IOException,
x.servlet.ServletException {
RowsForm rowsForm = (RowsForm) form ;
ArrayList rows = rowsForm.getRows() ;
RowForm rf0 = (RowForm) rows.get(0) ;
System.out.println("In RowsActionSave") ;
System.out.println("ID: " + rf0.getRowId()) ;
System.out.println("Property: " + rf0.getRowProperty1()) ;
ActionForward result=
mapping.findForward("rowspage");
return result;
}
}

//////////////// RowsPage.jsp ///////////


<TABLE><html:form action="/rowsActionSave.do">
<table>
<tr>
<th>id</th>
<th>property1</th>
</tr>
<logic:iterate name="rowsForm" property="rows" id="row"
type="test.RowForm">
<tr>
<td>
<bean:write name="row" property="rowId" />
<html:hidden name="row" property="rowId" />
</td>
<td>
<html:text name="row" property="rowProperty1" />
</td>

</tr>
</logic:iterate>
</table>
<html:submit property="Submit">Submit</html:submit>
</html:form>
</TABLE>
/////////////////// strutsconfig.xml ///////////
<form-bean name="rowsForm" type="test.RowsForm"/>
<forward name="rowspage" path="/RowsPage.jsp"/>
<action
path="/rowsActionShow"
type="test.RowsActionShow"
name="rowsForm"
scope="session"
validate="false">
</action>
<action
path="/rowsActionSave"
type="test.RowsActionSave"
name="rowsForm"
scope="session"
validate="false">
</action>

Re: here is a complete working example.


Author: Vicky Lamont (http://www.jguru.com/guru/viewbio.jsp?EID=1033674),
Dec 24, 2002
Hi Raj, I tried your example, it doesnot work. The exception I get when trying to
access the RowsPage.jsp is: Exception thrown by getter for property rows of bean
rowsForm Looking forward for your reply Thanks, Vicky

Re[2]: here is a complete working example.


Author: SaikrishnaRao K
(http://www.jguru.com/guru/viewbio.jsp?EID=1212791), Nov 24, 2004
Hi, Guys Just add the Following Code in the RowsForm.java
private ArrayList rows ;
Recompile and Redeploy the App It Should Work atleast it works for Me.

Re: here is a complete working example.


Author: Subramanyam Gandikota
(http://www.jguru.com/guru/viewbio.jsp?EID=1040772), Dec 24, 2002
I am working with struts 1.1-b2. When I run the code it throws the
following error:
Exception thrown by getter for property rows of bean rowsForm

in the jsp. Please help me on this .

Thanks a lot.
Subramanyam

Re[2]: here is a complete working example.


Author: Raj K (http://www.jguru.com/guru/viewbio.jsp?EID=1027421), Dec
31, 2002
I don't know why this error occurs when you try to run the JSP. for some
reason it does not load the form. It works as expected when you invoke the
"rowsActionShow.do"

http://localhost:8080/IndexedProps/rowsActionShow.do

and then make changes and submit the form. you can see the originale data and
the updated data in the debug messages that are in the Action classes
RowsActionShow.java and RowsActionSave.java

Re[3]: here is a complete working example.


Author: Raj K (http://www.jguru.com/guru/viewbio.jsp?EID=1027421),
Dec 31, 2002
on second thought.....I think it gives an exception because the form bean
RowsForm is not initialized and gets
initialized only when the rowsActionShow.do is invoked.......

Re[4]: here is a complete working example.


Author: Sunil Ravindran
(http://www.jguru.com/guru/viewbio.jsp?EID=1046123), Jan 14, 2003

The exception is thrown, because the first time the form is


loaded, the array rowId is not initialized, and in the method getRows(),
an exception is thrown at rowId.getLength(), initialize the array and
you shud be fine.
Re[5]: an easier alternative
Author: john anderson (http://www.jguru.com/guru/viewbio.jsp?EID=1206684), Oct 21
2004
Probably an easier alternative would be to use a data array to store it and retrieve it
from... here is an example. <%! String[] fieldstore; %> <% fieldstore = new String[40];
for (int t=0; t<40; t++) { fieldstore[t]=""; } for (int a=1;a<children.getLength();a+=2) {
(children.item(a).getAttributes().item(0).getNodeValue().equals(fieldstore[0]))
{ childelements = children.item(a).getChildNodes(); fieldstore[1] =
childelements.item(1).getChildNodes().item(1).getChildNodes().item(0).getNodeValue(
if (childelements.item(1).getChildNodes().getLength()>2) { fieldstore[2] =
childelements.item(1).getChildNodes().item(3).getChildNodes().item(0).getNodeValue(
} int e=0, c=0; for (int b=3; b<childelements.getLength();b+=2) { if
(childelements.item(b).getNodeName().equals("address")) { e=0;
if(childelements.item(b).getAttributes().item(0).getNodeValue().equals("home")) { } els
if(childelements.item(b).getAttributes().item(0).getNodeValue().equals("work"))
{ c=10; } else
if(childelements.item(b).getAttributes().item(0).getNodeValue().equals("postal")) { c=1
} addresselements = childelements.item(b).getChildNodes(); for (int
d=1;d<addresselements.getLength();d+=2) { if
(addresselements.item(d).getNodeName().equals("street")) { fieldstore .... so on, else if
(childelements.item(b).getNodeName().equals("dob")) { fieldstore[30] =
childelements.item(b).getChildNodes().item(0).getNodeValue();} else if
(childelements.item(b).getNodeName().equals("comments")) { fieldstore[31] =
childelements.item(b).getChildNodes().item(0).getNodeValue().trim();} } } }

Re: here is a complete working example.


Author: d b (http://www.jguru.com/guru/viewbio.jsp?EID=1119055), Oct 1, 2003
I have a question regarding the code.
In RowsActionShow.java, you are get an instance of the form before the jsp has
created it.
RowsForm rowsForm = (RowsForm) form;
what allows you to do this? I've been trying to mimic your example, and when I
do this my form = null. ... I'm trying to understand what I'm missing.
thanks, d

Re: here is a complete working example.


Author: aby chaturvedi (http://www.jguru.com/guru/viewbio.jsp?EID=1217698),
Jan 30, 2005
Raj I saw your code on the internet in connection to population of rows.However
on running the code i get an error RowForm Class not found.Could you help me in
running this code. Please help Aby
« previous beginning next »

Struts Tip #7 - Use Multibox to manage checkboxes


Location: http://www.jguru.com/faq/view.jsp?EID=925277
Created: Jun 24, 2002 Modified: 2002-09-06 04:41:23.732
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

Many applications need to use a large number of checkboxes to track options or


selected items. To help with this, Struts provides the multibox control. It's quite
handy but a little tricky to understand at first.

The multibox leverages the way HTML handles checkboxes. If the box is not checked,
the browser does not submit a value for the control. If the box is checked, then the
name of the control and its value are submitted. This behavior is the reason there is
a reset() method on the ActionForm. Since the browser will never signal that a box
has been un-checked, the only solution is to reset all the boxes, and then check the
ones that are now present in the request.

The multibox control is designed to use an array of Strings. Each element in the
array represents a checked box. To check a box, add a String to the array with the
box's value. To uncheck a box, remove the element from the array. (Sound familiar?)

When passed a value, the multibox control scans the elements of its array to see if
there is a match. If so, the box is checked. If not, the box is left unchecked. If the
user checks the box and submits the form, the box's value will be included in the
request. The controller will then add that box to the "checked" array. If a box is
unchecked, nothing is submitted, and nothing is added to the array. If the
ActionForm bean is kept in the session context, in between requests, the reset()
method needs to reduce the array to zero length (but not null).

In this example,

<logic:iterate id="item" property="items">


<html:multibox property="selectedItems">
<bean:write name="item"/>
</html:multibox>
<bean:write name="item"/>
</logic:iterate>

The labels for the individual checkboxes is in the items property. The list of selected
items is in an array named selectedItems. Items that are not selected are not
present in the selectedItems array. The multibox checks the selectedItems array for
the current item. If it is present, it writes a checked checkbox. If not, it writes an
unchecked checkbox.

Given an ActionForm setup like this

private String[] selectedItems = {};


private String[] items = {"UPS","FedEx","Airborne"};
public String[] getSelectedItems() {
return this.selectedItems;
}
public void setSelectedItems(String[] selectedItems) {
this.selectedItems = selectedItems;
}
The markup in the example would generate three checkboxes, labeled UPS, FedEx,
and Airborne.

<input type="checkbox" name="selectedItems" value="UPS">UPS


<input type="checkbox" name="selectedItems" value="FedEx">FedEx
<input type="checkbox" name="selectedItems" value="AirBorne">AirBorne

Initially, the selectedItems array would be empty. If UPS were checked and
submitted, it would become the equivalent of

private String[] selectedItems = {"UPS"};

If UPS and Airborne were both checked, it would become the equivalent of

private String[] selectedItems = {"UPS","Airborne"};

And when the checkboxes are rendered, the appropriate elements are automagically
checked by the multibox tag.

<input type="checkbox" name="selectedItems" value="UPS"


checked="checked">UPS
<input type="checkbox" name="selectedItems" value="FedEx">FedEx
<input type="checkbox" name="selectedItems" value="AirBorne"
checked="checked">AirBorne

To provide different sets of labels and values, the standard LabelValueBean class
[org.apache.struts.util.LabelValueBean] (since 1.1) can be used with the
multibox control.

<logic:iterate id="item" property="items">


<html:multibox property="selectedItems">
<bean:write name="item" property="value"/>
</html:multibox>
<bean:write name="item" property="label"/>
</logic:iterate>

HTH, Ted.

-----

Struts Tips are excerpts from the book Java Web Development with Struts. The tips
released twice weekly on the MVC-Programmers List. To subscribe, visit BaseBean
Engineering.

About Ted. Ted Husted is an active Struts Committer and co-author of Java Web
Development with Struts and Professional JSP Site Design. Ted also moderates the
Struts mailing list and the JGuru Struts FAQ.

Copyright Ted Husted 2002. All rights reserved.

---
MVC-Programmers mailing list
MVC-Programmers@basebeans.com
http://www.basebeans.com:8081/mailman/listinfo/mvc-programmers

Comments and alternative answers

Comments on Checkboxes in Struts.


Author: Mainak Ghosh (http://www.jguru.com/guru/viewbio.jsp?EID=975164), Aug
2, 2002
Thanks to Mr. Ted or this wonderful and helping article.

unable to utilize the multibox example in my struts application


Author: sam m (http://www.jguru.com/guru/viewbio.jsp?EID=1052110), Jan 30, 2003
I have tried using the multibox example but Struts is not invoking the set method
which takes String[] arguments, rather it invokes the set method which accepts only
one String argument.

My ActionForm class looks like this:

private String[] teamList;

public String[] getTeams()


{
return teamList;
}

public void setTeams(String[] teams)


{
System.out.println("setTeams(String[])-> size: " + teams.length);
teamList = teams;
}

public void setTeams(String team)


{
System.out.println("setTeams(String)-> " + team);
}

Also, I notice that getTeams() gets called for each "checkbox" entry in the JSP page.

What am I missing or doing incorrectly?

Thanks for the help.

Re: unable to utilize the multibox example in my struts application


Author: Isam Abdelhameed
(http://www.jguru.com/guru/viewbio.jsp?EID=1199121), Sep 14, 2004
How about naming your setter and getter to match you bean property; I mean
setTeamList() and getTeamList() instead of setTeams() and getTeams()

Problem using LabelValueBean[] instead of String[] with the multibox Struts tag
Author: Niall Hosiene (http://www.jguru.com/guru/viewbio.jsp?EID=1027863), Apr 14, 2003
I successfully used the code from tip #7 to create checkboxes. However, when moving from a String[]
array to a LabelValueBean[] array, I ran into problems. There wasn't a problem when typing in the url in
the browser and being forwarded to the appropriate JSP - everything rendered nicely. When I tried to
submit the form, I got the following exception:
java.lang.IllegalArgumentException: array element type mismatch
at java.lang.reflect.Array.set(Native Method)
at org.apache.commons.beanutils.ConvertUtils.convert(ConvertUtils.java:415)

Trying another tack and using a List of LabelValueBean objects instead of an array, I had a similar
result when submitting the form, just a slightly different exception:

java.lang.IllegalArgumentException: argument type mismatch


at java.lang.reflect.Method.invoke(Native Method)
at
org.apache.commons.beanutils.PropertyUtils.setSimpleProperty(PropertyUtils.java:1789)

Has anyone met this problem?

thanks,

N.

Re: Problem using LabelValueBean[] instead of String[] with the multibox


Struts tag
Author: Tariq Chalabi (http://www.jguru.com/guru/viewbio.jsp?EID=1110935),
Aug 26, 2003
Hi, I'm having exactly the same behaviour that you describe. Did you (or anyone
else) get a fix for this?

Re: Problem using LabelValueBean[] instead of String[] with the multibox


Struts tag
Author: Eduardo Lazarine
(http://www.jguru.com/guru/viewbio.jsp?EID=1199028), Nov 23, 2004
Hi, N.!

Maybe you should use LabelValueBean only during presentation of data (in Ted´s
example, the LabelValueBean[] is named "items").

For collecting results, the multibox tag will only parse String values. The
"selectedItems" property should still be String [] (and so their setter and getter
methods).
Hope it helps!

Cheers,

Eduardo.

Multibox-Iterate and Arrays with primitive Datatypes


Author: Timo Waldschmidt (http://www.jguru.com/guru/viewbio.jsp?EID=1084794),
Jun 13, 2003
Hi, as I read in the documentation, its not supported to iterate over an Array with
primitive Datatypes - instead I can only iterate over collections with objects and getter
and setter methods inside. That means, that your example with multibox doesn't work
in the kind you wrote - right? maybe the struts-docu is old or wrong? So why do you
write (JSP) <logic:iterate id="item"property="items"> ... (ActionForm) private
String[] items = {"UPS","FedEx","Airborne"}; that didn't work at me. What I want to
do is to iterate over an Collection. Within the Collection I have Objects with the
String- attribute Id. An this Id I want to use to name the value of the checkbox. Can
you help me to solve this problem? Greetings from Germany!

Re: Multibox-Iterate and Arrays with primitive Datatypes


Author: Barett McGavock
(http://www.jguru.com/guru/viewbio.jsp?EID=484005), Oct 22, 2004

A String is not a primitive data type.

The JSP can't see a private variable on the ActionForm. You'll need to have a
public get method in addition to the code you mentioned above.

multibox doesnt take indexed attribute


Author: Prakash Reddy (http://www.jguru.com/guru/viewbio.jsp?EID=1225652), Feb
8, 2005
I think the fact that html:multibox doesnt take the indexed attribute severely limits its
useful in advanced table like forms.

problem is if i have all the checkboxes checked


Author: sameep dawar (http://www.jguru.com/guru/viewbio.jsp?EID=1229501), Feb
26, 2005
so i want to retrieve the ids of the checked ones only but i expect the user to uncheck
the ones that he doesnt want 2 display pl help

Struts Tip #8 - Use result objects to transfer values


Location: http://www.jguru.com/faq/view.jsp?EID=933388
Created: Jul 1, 2002
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

Web developers tend to spend a lot of time tinkering with how data is input into an
application. This only makes sense -- after all, garbage in, garbage out -- right?
Absolutely! There is nothing more important then getting correct input from a user.
Much of the Struts framework centers on gathering and validating input. But that's
no reason to give output the short-shift. Presenting our hard-won data back to the
user can be just as important as gathering it in the first place.

Most presentation components, like JSP tags and Velocity templates, are quite adept
at rendering data from objects in a servlet context. So much so, that many
developers just tuck their data into one of the standard Collection classes and leave
the rest to the presentation layer. While this works, using a specialized result object
works even better.

A result object is simply a transfer object equipped with methods designed to give
the presentation layer a helping hand. Most often these are very simple methods,
like a helper to return the size of the collection as a standard JavaBean accessor.
Other common helpers could include a function to render text in all upper case, a
function to localize a date for the instant user, or an accessor that transform a string
of digits into a formatted telephone number.

Another good use of result object is to return the result of complex logical tests as a
simple value. If you find yourself wanting to do ANDs and ORs with JSP tags, think
about a helper method instead!

The result object itself is usually just a wrapper around some collection class. One
good approach is to have your result object implement the Collection interface so
that it can be used anywhere you are already using a Collection (or equivalent class).
The ModelResult class in the scaffold package is one example
[org.apache.scaffold.model.ModelResult]. This class is optimized for use with
another scaffold class, but the principles can be used with any type of data access
object.

Here are some of the helpers it provides.

int getSize() - Return the number of elements on the result list.


String getDescription() - Return a description of the result list.
Iterator getIterator() - Return an iterator for the result list.

When used with the Struts JSP tags, it becomes very easy to do things like print a
custom legend over the result and test whether the result was empty or not. The
following JSP code prints a description of the result object, but only prints the table
header when there is one or more element in the result.

<TABLE><TR><TD colspan="3">
<bean:write name="RESULT" property="size"/>
matches for
<bean:write name="RESULT" property="description"/>
</TD></TR>
<logic:notEqual name="RESULT" property="size" value="0" >
<TR>
<TH>id</TH><TH>article</TH><TH>contributed</TH>
</TR>
<TR>
<logic:iterate name="RESULT" property="iterator" id="row">
<TD><bean:write name="row" property="article"/></TD>
<TD>
<html:link forward="article" paramName="row" paramProperty="key"
paramId="key">
<bean:write name="row" property="title"/>
</html:link>
</TD>
<TD><bean:write name="row" property="contributed"/</TD>
</TR>
</logic:iterate>
</TR>
</logic:notEqual>
</TABLE>

When using the type of layered architecture Struts promotes, it's important to get as
much generic code as possible out of the presentation layer and up into the control
or business layers. If the result of method does not involve writing HTML markup, the
code probably belongs in a helper method. This lightens the load for the page and
makes it possible to reuse the helpers in another presentation environment.

You'll probably end up with the same amount of code either way. The question is
where can you put the code where it can be best managed and reused. Once you
start asking that question, you may be surprized how often result object helpers are
the answer!

HTH - Ted.

-----

Struts Tips are released weekly on the MVC-Programmers List. To subscribe, visit
BaseBean Engineering.

About Ted. Ted Husted is an active Struts Committer and one of the authors of
Professional JSP Site Design. Ted also moderates the Struts mailing list and the
JGuru Struts FAQ.

Copyright Ted Husted 2002. All rights reserved.

-----

MVC-Programmers mailing list


MVC-Programmers@basebeans.com
http://www.basebeans.com:8081/mailman/listinfo/mvc-programmers

Struts Tip #9 - Use rewrite to reference HTML assets


Location: http://www.jguru.com/faq/view.jsp?EID=941114
Created: Jul 8, 2002 Modified: 2002-09-06 04:39:42.422
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

The Struts <html:rewrite> tag can convert a context-relative URI into a base URI
that can be used to access style sheets, JavaScripts, images and other HTML assets.
For example,
<LINK rel="stylesheet" type="text/css"
HREF="<html:rewrite page='/assets/styles/base.css'/>">

If you wanted to hedge your bets about where the style sheets will be located, an
ActionForward may also be used.

<LINK rel="stylesheet" type="text/css"


HREF="<html:rewrite forward='baseStyle'/>">

Likewise, references to JavaScripts, as well as URIs to be processed by JavaScripts,


can be rendered this way.

<SCRIPT language='javascript'>
SRC='<html:rewrite page="/assets/scripts/remote.js"/>'>
</SCRIPT>
<SCRIPT>
<!--
function doScript(aScript) {
aBase = '<html:rewrite forward="scriptPreview"/>';
HC_doOpenRemote(aBase + '?script=' + aScript); }
// --
</SCRIPT>

In the latter example, we retrieve the base URI for the JavaScript function from an
ActionForward and then append the script number based to the function. This type of
function would usually be called from a hyperlink like this:

<A HREF='javascript:doScript(10011)'>10011</A>

that was generated using JSP code like this:

<A HREF='javascript:doScript(<bean:write name="row"


property="script"/>)'>
<bean:write name="row" property="script"/> </A>

Since we are calling a JavaScript function, we did not bother with a <html:link> tag
to provide URL encoding. The hyperlink will be handled client-side so maintaining the
session is not an issue. The URI generated by the <rewrite> tag, and subsequently
used by the Javascript, will be URL encoded, so that the session will be maintained if
cookies are not present.

HTH - Ted.

-----

Struts Tips are excerpts from the book Java Web Development with Struts. The tips
released twice weekly on the MVC-Programmers List. To subscribe, visit BaseBean
Engineering.

About Ted. Ted Husted is an active Struts Committer and co-author of Java Web
Development with Struts and Professional JSP Site Design. Ted also moderates the
Struts mailing list and the JGuru Struts FAQ.
Copyright Ted Husted 2002. All rights reserved.

---

MVC-Programmers mailing list


MVC-Programmers@basebeans.com
http://www.basebeans.com:8081/mailman/listinfo/mvc-programmers

Struts Tip #10 - Use Struts JSP Tags to create dynamic JavaScripts
Location: http://www.jguru.com/faq/view.jsp?EID=993519
Created: Sep 3, 2002 Modified: 2002-09-06 04:38:38.727
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

The Struts framework ensures that we can perform data validation without the
benefit if JavaScript. But that doesn't mean we can't use JavaScript in our Struts
applications. Most web developers rely on JavaScript to provided core features on the
presentation layer, and Struts developers are no exception.

Most JavaScript can be used on a Struts JSP like any other. After all, in the end, it all
comes down to HTML.

Because it all comes down to HTML, you can mix JSP tags in with references to your
JavaScript. The JSP code renders first, so by the time the browser sees it, any
dynamic references have been resolved, and it just looks just like a static reference.
Let's look at a script to open a remote window to preview a record from a database.

First a basic remote window script, just like you would use on a static page.

// Open window
function HC_openWin(newURL, newName, newFeatures, orgName) {
var newWin = open(newURL, newName, newFeatures);
if (newWin.opener == null) newWin.opener = window;
newWin.opener.name = orgName;
return newWin
}
// Open centered remote
function HC_doOpenRemote(aURL, newName, aHEIGHT, aWIDTH, aFeatures,
orgName){
if (aHEIGHT == "*"){ aHEIGHT = (screen.availHeight - 80) };
if (aWIDTH == "*"){ aWIDTH = (screen.availWidth - 30) };
var newFeatures = "height=" + aHEIGHT + ",innerHeight=" + aHEIGHT;
newFeatures += ",width=" + aWIDTH + ",innerWidth=" + aWIDTH;
if (window.screen){ var ah = (screen.availHeight - 30);
var aw = (screen.availWidth - 10);
var xc = (( aw - aWIDTH ) / 2);
var yc = (( ah - aHEIGHT ) / 2);
newFeatures += ",left=" + xc + ",screenX=" + xc;
newFeatures += ",top=" + yc + ",screenY=" + yc;
newFeatures += "," + aFeatures };
var newWin = HC_openWin(aURL, newName, newFeatures, orgName);
newWin.focus();
return newWin
}

We'll take this script as a given, since it is not the point of the exercise, and move on
to how it is called from the JavaServer Page.

We want to use this script to open different database records at different times. To
do this, we need to feed it a different URI to indicate which database record to open
this time. In many applications, the URI would look something like

/do/item/View?item=117

The "/do/item/View" part is relatively static. It just needs to be rewritten to maintain


the session, but we saw how to do that in Tip #9. We can store it as an
ActionForward and use the html:rewrite tag to render it at runtime.

Struts-config:

<forward name="item" path="/do/item/View"/>

JSP:

<html:rewrite forward="itemScript"/>

The dicey part is the ?item=117. This is the truly dynamic portion of the URI, and the
part that we actively need to pass to the script. That being so, lets make it a
parameter to our JavaScript function. Here's the result:

<script>
<!--
function doItem(aItem) {
aBase = '<html:rewrite forward="item"/>';
HC_doOpenRemote(aBase + '?item=' +
aItem,'preview','*','600','scrollbars','form');
}
// -->
</script>

Note that we only need to pass the item number (e.g. "117") to this function. The
function then takes the base part of the URI and concaternates it with the query
string and our parameter.

All that's left now is passing the parameter to the script. The item number would be
passed to the page within a JavaBean, so we can use bean:write for that:

<a href='javascript:doItem(<bean:write name="itemForm"


property="item"/>)'>Item Number</a>

At runtime, this would resolve to

<a href='javascript:doItem(117)'>Item Number</a>


Since the JavaScript is rewriting the URI, we don't have to worry about that part of it
here, and can use a conventional hyperlink tag.

<h4>Whole Cloth Approach</h4>

You could also just write the entire script into the page from scratch:

<SCRIPT>
<!--
<bean:write name="fancyForm" property="javaScript" filter="off"/>
// -->
</SCRIPT>

This will write out whatever is returned by the String fancyForm.getJavaScript()


method. This lets you create the JavaScript by any means necessary. The Struts
Validator uses this approach to create a complex series of scripts that are rendered
into the page from a single JSP tag.

Of course, any other element or HTML assets can also be created this way.

<h4>Rename Submit</h4>

Some JavaScripts may try to call the submit operation for a form. By default, the
<html:submit> button is also named (surprise) submit. To avoid conflicts, give the
submit button another name.

<h4>Formless Buttons</h4>

It is often useful to use a button to represent a hyperlink or JavaScript action.


Problem is, the <html:form> tag expects each form to have a corresponding
ActionForm bean. A hyperlink and many JavaScript actions don't need parameters
and so don't need a form-bean The solution is to give the tag what it wants and
define a simple form with no properties.

public class BlankForm extends ValidatorForm { // blank form };

This form can then be cited in the Struts configuration whenever a "formless" form is
needed. For example, to provide a JavaScript back button:

struts-config:

<action
path="/Back" type="org.apache.struts.ForwardAction"
name="blankForm"
scope="request"
validate="false"
parameter="/do/Menu"/>

JavaServer Page:
<html:form action="/Back">
<html:button property"page" onclick="history.go(-
1)">DONE</html:button>
</html:form>

HTH - Ted.

-----

Struts Tips are excerpts from the book Java Web Development with Struts. The tips
released twice weekly on the MVC-Programmers List. To subscribe, visit BaseBean
Engineering.

About Ted. Ted Husted is an active Struts Committer and co-author of Java Web
Development with Struts and Professional JSP Site Design. Ted also moderates the
Struts mailing list and the JGuru Struts FAQ.

Copyright Ted Husted 2002. All rights reserved.

---

MVC-Programmers mailing list


MVC-Programmers@basebeans.com
http://www.basebeans.com:8081/mailman/listinfo/mvc-programmers

Comments and alternative answers

broken link for Struts book


Author: Christopher Koenigsberg
(http://www.jguru.com/guru/viewbio.jsp?EID=722897), Sep 4, 2002

The hyperlink for Ted's upcoming book is broken in this FAQ entry -- it mistakenly
came out when you posted it, as being under www.jguru.com.

I think the correct URL at this point (might change when the book comes out?) should
be http://www.husted.com/about/scaffolding.

Happy reading,

how can I determine the version of a struts.jar? I'm trying to help a


customer debug a problem related to his using struts with WebLogic. I
asked what version he is using; instead of telling me, he sent his struts.jar
file. I have unpacked it, but I don't know where to look. He did not send the
documentation with it. Is there an easy way for me to tell from the files in
struts.jar? Thanks, Wayne Scott
Location: http://www.jguru.com/faq/view.jsp?EID=993521
Created: Sep 3, 2002
Author: Rob Parker (http://www.jguru.com/guru/viewbio.jsp?EID=914522) Question
originally posed by Wayne Scott
(http://www.jguru.com/guru/viewbio.jsp?EID=26734

The easiest way I can think of it to unzip the jar and look at the manifest.mf file. The
manifest should contain a line called Implementation Version. Here is my
manifest.mf:

Manifest-Version: 1.0
Implementation-Version: 1.0.2
Specification-Title: Struts Framework
Specification-Version: 1.0
Implementation-Title: Struts Framework
Extension-Name: Struts Framework
Created-By: Ant 1.4.1
Implementation-Vendor-Id: org.apache
Implementation-Vendor: Apache Software Foundation
Specification-Vendor: Apache Software Foundation

So my version is 1.0.2

Rob
Comments and alternative answers

Not for Struts 1.1b2 !!!


Author: Nusrat Khan (http://www.jguru.com/guru/viewbio.jsp?EID=1032225), Nov
29, 2002
In Struts 1.1b2 : Manifest-Version: 1.0 Implementation-Version: 1.0 Specification-
Title: Struts Framework Specification-Version: 1.0 Implementation-Title: Struts
Framework Extension-Name: Struts Framework Created-By: Ant 1.4.1 Class-Path:
commons-beanutils.jar commons-collections.jar commons-dbcp .jar commons-
digester.jar commons-logging.jar commons-pool.jar common s-services.jar commons-
validator.jar jakarta-oro.jar Implementation-Vendor-Id: org.apache Implementation-
Vendor: Apache Software Foundation Specification-Vendor: Apache Software
Foundation

Other solution
Author: Nusrat Khan (http://www.jguru.com/guru/viewbio.jsp?EID=1032225), Nov
29, 2002
The subpath 'digester' existe only on 1.0.2 and not on 1.1b

<html:options> tag help Hi,


I get a result set from a query which has id and description, now I have to
show the it in select tag some thing like this, <select name="option">
<option value="id1">desc1</option> <option
value="id2">desc2</option> </select> I think that i can use
<html:options> tag which will do my work, but i m not sure how to use it,
how do to define the bean, and also how to set the properties, does anyone
have sample code of the bean and the tag for that bean, it will help me alot..
Thanx
Ashish
Location: http://www.jguru.com/faq/view.jsp?EID=993529
Created: Sep 3, 2002
Author: Paul Sijpkes (http://www.jguru.com/guru/viewbio.jsp?EID=954062)
Question originally posed by Ashish Kulkarni
(http://www.jguru.com/guru/viewbio.jsp?EID=132372

Hi Ashish,

You will need to do something like this.

<html:select name="myPreselectedItemBean">
<html:options name="myCollection" property="myValue"
labelProperty="myLabel"/>
</html:select>

Notice that the select tag has a "myPreselectedItemBean" bean associated with it,
this bean must be in some scope ie. session, request etc..

The same goes for the "myCollection" bean, this is a bit more complex. Took me a
while to get my head around...

"myCollection" should be either be an Object extending java.util.Collection or an


array of Objects. It can't be a simple type (eg. int[]).

"myCollection" should be made up of other beans, with a getMyValue() and


getMyLabelProperty() method.

eg.
public class OptionItem
{
public OptionItem()
{
}

String myValue;
String myLabel;

public String getMyValue()


{
return myValue;
}

public void setMyValue(String myValue)


{
this.myValue = myValue;
}

public String getMyLabel()


{
return myLabel;
}

public void setMyLabel(String myLabel)


{
this.myLabel = myLabel;
}
}

I normally create a Vector and then populate it with these sort of beans.

I hope this is helpful to you.

cheers,
Paul Sijpkes
Comments and alternative answers

Display value in the option


Author: jbil jbil (http://www.jguru.com/guru/viewbio.jsp?EID=1003382), Sep 24,
2002

Once I fill in the option list, I would like to show (add selected property) one of the
values (ie. the one that is stored in the DB)

I have not a clear idea how to do that (tag html:options or other). Could anyone give
me a hint? Thank you.

Jorge

Re: Display value in the option


Author: jbil jbil (http://www.jguru.com/guru/viewbio.jsp?EID=1003382), Sep 24,
2002

I answer to myself since I've found the solution. Indeed I used html:options struts
tag to set a value by default in the combo box.

If that can help anyone...

Jorge

Re[2]: Display value in the option


Author: Parthasarathy Madhira
(http://www.jguru.com/guru/viewbio.jsp?EID=1082512), May 7, 2003
Hello, I've to do the same task ie populating a html:select tag with the values
from Database. But I always get an error as this:
javax.servlet.jsp.JspException: Cannot find bean under name userWorkGroup
at org.apache.struts.taglib.html.OptionsTag.getIterator(OptionsTag.java:411) at
org.apache.struts.taglib.html.OptionsTag.doEndTag(OptionsTag.java:236) at
org.apache.jsp.inbox$jsp._jspService(inbox$jsp.java:193) at
org.apache.jasper.runtime.HttpJspBase.service(HttpJspBase.java:107)

Re[3]: Display value in the option


Author: SESHAGIRI VARANASI
(http://www.jguru.com/guru/viewbio.jsp?EID=1128652), Dec 28, 2003
hi Parthasarathy, I too faced the same problem. I got around that by setting
the 'userWorkGroup' in the request scope. Something like this:
request.setAttribute("userWorkGroup", userWorkGroup); try this, hope this
helps u, Seshu

Hi Sheshagiri I've to do the same task ie populating a html:select


tag with the values from Database.
Author: Rahul Raaj
(http://www.jguru.com/guru/viewbio.jsp?EID=1240889), Jun 14, 2005
I've to do the same task ie populating a html:select tag with the values
from Database.
I am using LabelValueBean for Label/value pairs.But i am unable to do
it.Is there any need to make a seperate class for collections.Could you
give me some idea how to accomplish this task.
Some sample code can help me better.
thanks in advance

Re[3]: Display value in the option


Author: Jeffrey Lu
(http://www.jguru.com/guru/viewbio.jsp?EID=1221269), Jan 14, 2005
Hi Parthasarathy, I have exactly the same problem like you discribe. Did
you get it resolved and how?

Re[3]: Display value in the option


Author: JP Fiset (http://www.jguru.com/guru/viewbio.jsp?EID=1250088),
Jun 23, 2005
Turns out that <html:options> looks specifically for a JSP bean. If you
want to populate your selection using a bean collection from the action
form, you need to use the tag:

<html:optionsCollection property="beanCollectionName"
value="valuePropery" label="labelProperty"/>

Re[2]: Display value in the option


Author: Tara s (http://www.jguru.com/guru/viewbio.jsp?EID=1160082), Apr
30, 2004
How set your values to default? can you please give any sample code?
I am able to populate the values in jsp form, using

<html:select property="regionList" name="reportForm" multiple="true" >


<html:optionsCollection property="regions" /> </html:select>

but trying to show some vales are selected by defalt


like <option value="NE" SELECTED>NE</option>

Re[3]: Display value in the option


Author: Tara s (http://www.jguru.com/guru/viewbio.jsp?EID=1160082),
Apr 30, 2004
now I got ... in the form bean
set the array values as
private String[] regionList = {"NY","NY"};

Re: Display value in the option


Author: Nikesh Goyal (http://www.jguru.com/guru/viewbio.jsp?EID=1207733),
Oct 28, 2004
I think u r getting Values in Drop Down through Collection in the form bean...If u
want to show some values then u will have to made the code in form bean... e.g::::
Suppose u r getting Arraylist Sample form Form bean.. Make a Duplicate Arraylist
named as Sample1 in Form bean... private Collection sample; private Collection
sample1; public Collection getSample(){ return sample; } public Collection
getSample1(){ return sample1; } public void setSample1(Sample sample1){
this.sample1 = sample1; } public void setSample(Collection sample) { Iterator
iter=sample.iterator(); int i=0; while(iter.hasNext()){ Sample
a=(Sample)iter.next(); if((i==1)||(i==6)){ this.sample1.add(a); } i++; }
this.sample= sample; } and use in sample1 instead of sample in JSP page in
HTML collection property tag... if u have any prob in Code then Feel free to ask
any questions.... Regards Nikesh Goyal(nikesh_bit@yahoo.co.uk)

Re: Display value in the option


Author: Sachin Joshi (http://www.jguru.com/guru/viewbio.jsp?EID=1235425),
Mar 29, 2005
you can use org.apache.struts.util.LabelValueBean from Struts util package, which
is provided for this purpose only. Hope this helps REgards, Sachin

Needed first element to be hardcoded


Author: Harsh Sugandhi (http://www.jguru.com/guru/viewbio.jsp?EID=401509), Apr
18, 2004
Hi! I want to make the first option to be hard coded as - All Is there any idea for that?
Thanx. Harsh

Re: Needed first element to be hardcoded


Author: Gregor Berginc (http://www.jguru.com/guru/viewbio.jsp?EID=1168704),
May 6, 2004
If you are using a Collection, why don't you add the "All" item at index 0 after
you fill the Collection?

Alternatively, you can first put the "All" item and then fill the rest of the
Collection (array).

Hope it helps,

lemmy

two dynamic master detail options


Author: bagus prabawa
(http://www.jguru.com/guru/viewbio.jsp?EID=874575), Jun 1, 2004
i have two options derived dynamicly from DB, Category and Detail, each
category has their own detail, for example :
category : four wheels detail : car,trucks
category : two wheels detail : motorcycle, bike
i want if user change options in category, the details option also change
accordingly.
can i do these with struts options?? any suggestion???example would be
excellent....
Thanks

how to fill the select tag using some collection in struts


Author: padam jain (http://www.jguru.com/guru/viewbio.jsp?EID=1187756), Jul 21,
2004
hi one thing that u can try <html:select property="propertyName"> <html:options
collection="resultName" property="yourIDvalue" labelProperty="descript">
</html:options> </html:select> hope this will help u

Populating data from the database into the jsp form onload
Author: Saritha V (http://www.jguru.com/guru/viewbio.jsp?EID=1055612), Jul 22,
2004
Hello, After reading all messages I understand that, the collection should contain the
valueobjects that holds <Id,desc> and we have set this collection either in the request
or sessions scope. But Where should I have to build this collection and place this in
request scope. Will that be in the constructor of the ActionForm? I guess not because
there i will not have the request object. or In the Action class?. how the whole thing
works? When we use struts, what is the sequence of steps that have to be followed to
pre populate data in JSP. do we have to write anything onLoad? Please clarify my
doubts. Thank you in advance Saritha

Re: Populating data from the database into the jsp form onload
Author: Samir Mishra (http://www.jguru.com/guru/viewbio.jsp?EID=1211110),
Nov 15, 2004
Normally these kinds of operations are done in middle-tier. In your action class
which will redirect to the JSP page you can populate the arraylist or any other
collection object and set the same to request / session (recommended) and then
you can access the same anywhere.

Cheers - Samir

Property attribute required in html:select


Author: bhushan dravid (http://www.jguru.com/guru/viewbio.jsp?EID=1240005),
May 5, 2005
Hi Paul,

First of all you have explained your answer very nicely.. But there was one problem,
that i faced while I was trying to implement your logic.

Jboss was giving error that "property attribute of <html:select> is mandatory." Cud u
plz help me on that...

How does it all connect together with a bean html:options and form and action-
Please HELP!!!
Author: M C (http://www.jguru.com/guru/viewbio.jsp?EID=1255949), Jul 31, 2005
Hi I am VERY new at this..a designer moving into doing the code using struts...and I
have to do exactly this (just don't know how although your postings have helped me
understand it a bit)...so could you please tell me what I need to do in the actual
beans...as in where is "myCollection" coming from, and what am I doing in the
bean"myPreselectedItemBean"..am I just adding gettters and setters?

Where does the other class go 'OptionItem' that you mentioned...I guess what I mena
is is it just a POJO or does that stuff go in my Form.java class. So far there is a
LogicFacadeBean that has interactions with the Form.java class where there are a lot
of getters and setters...ther is a Actions.java class and then there is my JSP where I am
trying to display a list of strings from my db in a drop-down....also where do I put my
formulate sql query in?

As you can guess I am a novice to struts and hibernate...so any help will be greatly
appreciated.

cheers

Struts:Calling a Action Class from another Action class


Hi,
I have a situation where I want to forward to a Action class from another
Action Class.For Example:When ever user click any link on the page,first the
SecurityAction class should be called and if it is successful forward to
Another Action Class which does the Business Related thing and if it is not
Security is not successful send it to Login page. What needs to be done for
this?Can I get sample code for this??
Location: http://www.jguru.com/faq/view.jsp?EID=993533
Created: Sep 3, 2002
Author: James Page (http://www.jguru.com/guru/viewbio.jsp?EID=386536)
Question originally posed by chandan singh
(http://www.jguru.com/guru/viewbio.jsp?EID=986900

You can easily forward between actions by specifiying the action as another forward
in the struts configuration file:

<action path="/actions/firstAction"
type="example.SecurityAction"
scope="request">
<forward name="success"
path="/actions/secondAction.do"/>
<forward name="failure"
path="/pages/login.jsp"/>
</action>

<action path="/actions/secondAction"
type="example.BusinessAction"
scope="request">
<forward name="success" page="/pages/businessPage.jsp"/>
</action>

Alternatively, you can create an ActionForward object on the fly so that you could
redirect the user to a protected URL request that has been stored in the session prior
to going throught security.

This can be combined quite neatly with the standard security mechanism provided
with Servlet/JSP applications - does depend a bit on which application server/web
server vendor you are using! I think that the standard identifier in the request is
'j_target_url' - you could use the value of this session attribute to create an
ActionForward in your SecurityAction class and forward the user to the original URL
they requested - note that you will also have to authenticate the user with the web
container as well!

Cheers

James

Comments and alternative answers

Can this not be easily bypassed?


Author: Mr Bean (http://www.jguru.com/guru/viewbio.jsp?EID=998184), Sep 12,
2002
What happens if someone manually goes to the URL /actions/secondAction.do? If my
understanding is correct then the secondAction would still be required to do its own
check to make sure authentication had been completed, makeing this approach no
better than manually performing this check in every action.

Re: Can this not be easily bypassed?


Author: James Page (http://www.jguru.com/guru/viewbio.jsp?EID=386536), Sep
20, 2002

The example configuration does not demonstrate to the 'protected' functionality.

To do this, the second action would need to be in a 'protected' area.

See the <security-constraint> section of the web.xml file on details of how to set
this up.

Re[2]: Can this not be easily bypassed?


Author: V M (http://www.jguru.com/guru/viewbio.jsp?EID=1034332), Dec 5,
2002
I am new to struts. Have a comment, My understanding is that every request
gets routed from the Controller class so would it be a good idea to put the user
authentication part of the code in the controller class.

What if the second .do is in a different web app


Author: Ugo Posada Zabala
(http://www.jguru.com/guru/viewbio.jsp?EID=1040388), Apr 2, 2003
Would it still be possible to use the forward to redirect to an action that is
located in a different war. In that case, should I append the context before
the action logic name?

Thanks

Re[3]: Can this not be easily bypassed?


Author: abhishek shrivastava
(http://www.jguru.com/guru/viewbio.jsp?EID=1219583), Jan 6, 2005
Hi.. Your Controller class is the ActionServlet class in Struts.u cann't have
ur own ActionServlet class declared in web.xml of the struts application.
i.e. u can use MyActionServlet in web.xml where u have a class class
MyActionServlet extends ActionServlet { } its better to have validate ur jsp
page data in the ActionForm itself (using the validate method) which is
called prior to the call of ActionServlet. Good luck... Abhishek
Outputting nested bean properties Dear All,

I am starting out writing a Struts app which is a web version of a client Java
app. I have a data type, called Searcher, which represents both the criteria
for a search and the results back from a search. The Searcher contains a
PartList, obtained by calling getPartList. The PartList represents a list of
parts. Because the number and name of the different part attributes are
unknown until they are retreived from the database however, the actual
keys are stored in the part list in a Vector.
Searcher
|
+-- PartList (Vector containing Parts)
|
+-- keys list (Vector of Strings) Part (Hashtable)

in order to print the various attributes of a part, you need to:

Searcher searcher = ....


PartList list = searcher.getPartList();

for(int i=0;i<list.size();i++) // work through list of parts


{
Part p = (Part)list.elementAt(i);
for(int attr=0;attr<list.getFieldCount();attr++)
{
System.out.println("Attribute " + list.getLabelFor(attr) +
" has value " + p.get(list.getDbNameFor(attr)) );

}
}

What I want to do is similar to the above, only on the JSP page. I need to
(1) create a form with fields for each attribute to allow the user to do a
search, and (2) iterate through the PartList in any result and display the
parts in a table.

I have heard about the ability of the newer tags to be able to iterate
through Map objects (Parts) and indexed objects (such as the PartList). I
have a handle to the searcher object via a useBean property, but do not
know how I can define another handle that holds the part list. I have tried:

<jsp:useBean id="searcher" scope="session"


type="com.aeroint.partsmarking.valueobjects.Searcher"/>

<jsp:useBean id="partlist"
type="com.aeroint.partsmarking.valueobjects.PartList">
<jsp:getProperty name="searcher" property="partList"/>
</jsp:useBean>
I realise this is a large request. If someone can help me iron out this
'obtaining secondary handle' bit I would be very grateful,
Thanks, DS
Location: http://www.jguru.com/faq/view.jsp?EID=993534
Created: Sep 3, 2002
Author: Christopher Koenigsberg
(http://www.jguru.com/guru/viewbio.jsp?EID=722897) Question originally posed by
Dave Smith PREMIUM (http://www.jguru.com/guru/viewbio.jsp?EID=929815

OK here is a reconstruction of my example that got nuked, please feel free to


correct, enhance, comment etc.

This example is using Struts tags ("logic:present"/notPresent, "logic:iterate" nested 2


levels, "bean:size", "logic:greaterThan"/lessEqual, and "bean:write"), no scriptlets,
to display search results, presumably returned previously and already set into
session scope, as "your2DResultsCollectionBean", assumed to be a 2-dimensional
implementation of java.util.Collections interface (e.g. "List" rows of "List" columns, of
"String" value):

<logic:notPresent name="your2DResultsCollectionBean" scope="session">


<h3>Sorry, no results were returned! (contact the Webmaster?)</h3>
</logic:notPresent>

<logic:present name="your2DResultsCollectionBean" scope="session">


<bean:size id="numResults" name="your2DResultsCollectionBean"
scope="session" />

<logic:lessEqual value="0" name="numResults" scope="page">


<h3>Sorry, your search returned zero results! Please try again!</h3>
</logic:lessEqual>

<logic:greaterThan value="0" name="numResults" scope="page">


<p><strong> Congratulations, your search returned</strong></p>
<h4> <bean:write name="numResults" scope="page"/> results:</h4>
<table>

<logic:iterate id="ResultsRowCollectionBean"
name="your2DResultsCollectionBean"
indexId="rowNum" scope="request">

<logic:present name="ResultsRowCollectionBean scope="page">


<tr>
<td>
Result row number:
<bean:write name="rowNum" scope="page"/>
</td>
<logic:iterate id="ResultsColumnStringBean"
name="ResultsRowCollectionBean"
indexId="ColNum" type="java.lang.String"
scope="page">

<logic:present name="ResultsColumnStringBean"
scope="page">
<td>
ColNum
<bean:write name="colNum"
scope="page"/>
,
Value:
<!-- the "filter=false" will
preserve any embedded HTML formatting tags -->
<bean:write
name="ResultsColumnStringBean" scope="page" filter="false"/>
</td>
</logic:present>

<logic:notPresent name="ResultsColumn"
scope="page">
<td>
(empty column)
</td>
</logic:notPresent>
</logic:iterate>

</tr>
</logic:present>

<logic:notPresent name="ResultsRow" scope="page">


<tr>tr<td>td
( empty row)
</td></tr>
</logic:notPresent>

</logic:iterate>
</table>
</logic:greaterThan>

</logic:present>

Note that if the "your2DResultsCollectionBean" at the outer level implemented


java.util.Map rather than java.util.List, you would have to use "key" or "value" in
accessing the current row inside the outer iterator e.g. say if you had rowNumber as
the Map key and rowContents as a "List" as the value of the Map element for that
row, you would name something like "resultsRowCollectionBean.value", as the
"name" attribute of the source bean for the inner logic:iterate, and
"resultsRowCollectionBean.key" would give you the Map getKey which in this case
would presumably equal your rowNumber...

Also if your columns did not just contain Strings, you would have to call their
toString() or something like that, in displaying the column contents (e.g. the
"ResultsColumnStringBean" would need some explicit accessor method to be called
by the innermost bean:write, if it wasn't just a String).

Comments and alternative answers

Iteration
Author: Dimitrios Karapiperis
(http://www.jguru.com/guru/viewbio.jsp?EID=1067256), Mar 18, 2003
the example doesn't work on my case.
I have a bean which is a vector (users) that each node contains another vector which
are the fields of each user.
When I comamnd the inner iteration I get the error "javax.servlet.ServletException:
Cannot create iterator for this collection".

Many thanx

logic:iterate using offset to iterating through multiple arrays at the same time...
Author: doug wigginton (http://www.jguru.com/guru/viewbio.jsp?EID=1209247),
Nov 4, 2004

I spent a little time figuring out how to iterate through mutliple arrays under
essentially one loop using logic:iterate in struts. I'm posting what I came up within the
hopes that it will help someone else!

If you have three arrays say:

Joe, Bill, Sue


87, 60, 90
B,D,A and you want to output:

Joe 87 B

Bill 60 D

Sue 90 A

you can use the indexId, offset and length parameters in the iterate tag to step through
all three arrays at the same time:

( the key is offset="i" length="1" )

<jsp:useBean id="studentList" scope="request" class="java.util.ArrayList" />

<jsp:useBean id="scoreList" scope="request" class="java.util.ArrayList" />

<jsp:useBean id="gradeList" scope="request" class="java.util.ArrayList" />

<logic:iterate id="student" name="studentList" indexId="i">

<bean:write name="student" property="name"/>


<logic:iterate id="score" name="scoreList" offset="i" length="1">

<bean:write name="score" property="numericScore"/>

</logic:iterate>

<logic:iterate id="grade" name="gradeList" offset="i" length="1">

<bean:write name="grade" property="letterGrade"/>

</logic:iterate>

</logic:iterate>

Struts Tip #11 - Use smart forwarding to dispatch actions


Location: http://www.jguru.com/faq/view.jsp?EID=995474
Created: Sep 6, 2002
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

A key component to the Struts framework is the ActionForward. A deceptively simple


object, all the ActionForward does is associate a system path with a logical name.
But this object gives the framework much of its power and flexibility.

The workhorse of the framework are the Action objects. When an Action completes,
it returns an ActionForward to the controller. The controller then passes control to
whatever path is indicated by the ActionForward. Most times, the Action doesn't
know anything about the path. It just knows to forward to "success" or "failure". Of
course some Actions are more flexible and might return any number of different
forwards depending on the circumstances. An Action could start by retrieving a
record and then forward to "copy" or "delete", depending on what the user
requested.

There's a similar situation when an application processes a form. Most forms contain
a number of fields that you can enter or edit, with an OK or CANCEL button. But
other times, we might want to do several other things, like "DELETE" or "SAVE AS
NEW". We could use a DispatchAction (Tip #2), but that requires making changes to
how an Action is coded.

The Struts framework already provides ActionForwards to describe how control flows
through the application. An action mapping can have any number of local forwards.
So it follows that we should be able to use local forwards to dispatch control. Each of
the local forwards can represent one of the form operations. So, for example, the
"copy" forward can send control to the copy action, and the "delete"forward can send
control to the delete action. Something like this

<action name="articleForm" path="/do/article/Submit" ... >


<forward name="create" path="/do/article/Create"/>
<forward name="save" path="/do/article/Store"/>
<forward name="delete" path="/do/article/Recycle"/>
<forward name="cancel" path="/do/Menu"/>
</action>

A HTML form can only submit to one location, so we have to start with a single
"clearinghouse" action that can be the target of the form. This action needs to be
able to determine the operation, and then send control to the appropriate local
forward. This is very similar to what the DispatchAction does. It looks up a
parameter in the request and uses the value of that parameter to select a method.

Doing the same thing in an action takes a single line in the perform() [or execute()]
method:

public final class RelayAction extends Action {


public ActionForward perform(
ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws IOException,
ServletException {

return
mapping.findForward(request.getParameter(Tokens.DISPATCH));

}
} // end RelayAction

So, if we have a parameter like

dispatch=delete

Our RelayAction will look up the "delete" forward and return it to the controller.
Working from the example, this would cause the controller to forward to
/do/article/Recycle. The Recycle action would then fire as if it had been the target of
the action in the first place.

In the form, we can use the same JavaScript function as we used for the
DispatchAction in Tip #2:

<html:hidden property="dispatch" value="error"/>


function set(target){document.forms[0].dispatch.value=target;}
<html:submit onclick="set('save');">SAVE</html:submit>
<html:submit onclick="set('create');">SAVE AS NEW</html:submitl>
<html:submit onclick="set('delete);">DELETE</html:submit>

This sets the dispatch property to whatever button the user presses, which in turn
selects the corresponding ActionForward for the mapping.

Since the RelayAction is configured through its action-mapping, it can be used as


many times as needed by your application without subclassing.
In the next tip, we will look at ways to use RelayAction and some like-minded friends
to build config-based menu systems.

HTH, Ted.

-----

Struts Tips are excerpts from the book Java Web Development with Struts. The tips
released twice weekly on the MVC-Programmers List. To subscribe, visit BaseBean
Engineering.

About Ted. Ted Husted is an active Struts Committer and co-author of Java Web
Development with Struts and Professional JSP Site Design. Ted also moderates the
Struts mailing list and the JGuru Struts FAQ.

Copyright Ted Husted 2002. All rights reserved.

Comments and alternative answers

Parameter config not allowed for RelayAction?


Author: Ted Schrader (http://www.jguru.com/guru/viewbio.jsp?EID=1059153), Feb
21, 2003
Hi Ted,

I was wondering why the RelayAction's parameter name cannot be set via the
action mapping's parameter attribute. Without it, we all have to live with the
dispatch request parameter name, which is okay for now. I couldn't find any bugs on
Apache Bugzilla or any explanation in the source or Struts In Action.

My argument for opening the parameter attribute is based on two related points:

• The Javadoc for DispatchAction implies the convention of using method as


the dispatch name, which doesn't have to be followed (personally, I like
dispatch better).
• The RelayAction could contain both regular Actions and DispatchActions
as it's forwarding targets. It would be nice to keep the parameter name of the
RelayAction in synch with the target DispatchActions. Of course, this
assumes that all DispatchActions will have the same parameter name, which,
within a module, isn't that big of a leap.

A quick anecdote:
All my DispatchActions use method as the parameter and the beans are set as such.
Now, in order to utilise RelayAction, I've revisited those affected beans and action
mappings and renamed method to dispatch. So, now I've got just a few
DispatchActions that expect dispatch and all the rest expect method.
So, I suppose I would also like to know if my design is just not playing well with
others, or if RelayAction is not yet as amicable as possible.

Thanks,

Ted Schrader

Struts modules with Lookup dispatch action


Author: Sanjay Sreenivas (http://www.jguru.com/guru/viewbio.jsp?EID=1247780),
Jun 9, 2005
I am working on struts modules with lookup dispatch action. For all forms i am
having only one action servlet and action class in which i am storing datas in to the
database. All the forms have only one submit button. But i perform the actions using
lookup dispatch for each buttons of different forms rather than using execute method.
It throws error saying the request action does not have handler for parameter. Error
thrown in browser Request[/add] does not contain handler parameter named
action Can any body help me out on this problem

Action Form getter methods and the user's locale I posed a question a few
days ago that I realize probably was not worded very clearly. Zac Jacobson
recommended that I resubmit the question and try again. (Thanks Zac, for
the advice). Here's what I know:

1. The ActionForm's getter methods present data for the construction of


the HTML page.
2. If you want data to be formatted in a locale specific way (for example
presenting the date December 31, 2002 as 31.12.2002 to a user in the
UK), then you need to know the user's locale object. Given the locale
object, Java provides numerous locale specific formatting methods
for both dates and numbers.
3. The locale object is available via a getLocale method in the
HTTPRequest object.

Here's my question: How do I put the locale object together with the
ActionForm's getter methods? Should I store a member variable copy of the
locale in the ActionForm class, thereby making it available to the
ActionForm's getter methods? If so, then how should I set that member
variable--via the reset() method, which has access to the HTTPRequest
object, or through the Action class's perform() method, or via some other
mechanism? Is there a constructor for the ActionForm class or some sort of
init() method that I could use? How are people handling this problem? I18N
is the hot buzzword nowadays, and it is more than just getting your
prompts translated into another language--it also involves data formatting,
so somebody must be doing this.
Location: http://www.jguru.com/faq/view.jsp?EID=998914
Created: Sep 13, 2002
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by Dan Desch
(http://www.jguru.com/guru/viewbio.jsp?EID=827173
From a MVC perspective, it's really best to think of the ActionForm as a denizen of
the control layer. It is a data transfer object that is used to capture input posted by
the view and ready it for transfer to the model layer. As such, it's best thought of a
dumb data carrier -- an encapsulation of the input and other output other objects
need to do their jobs.

If an application is localized, then the localization should be represented in the


model. So, the best place thing is for the ActionForm to be populate with pre-
localized data before it is sent down to the presentation layer.

Struts provides a standard Locale object in the user's session that you can hand up
to the model so that it can return the localized data.

Another approach would be to add the locale object to the ActionForm and have the
getters use that to localize the property when it is returned. The request is passed to
the Reset method, so you can have the ActionForm grab the locale from the session
whenever reset it called. In this case, you might want to have both getAmount and
getAmountDisplay properties, to return either the "raw" or formatted versions. But,
IMHO, its preferable to have only getAmountDisplay on the ActionForm and then put
the getAmount and getAmountDisplay properties on the model bean instead.

HTH, Ted.

Comments and alternative answers

What about DynaActionForm?


Author: Shai Almog (http://www.jguru.com/guru/viewbio.jsp?EID=501707), Jan 14,
2003

We used a such a solution in our application in which the base ActionForm adds
support for Locale and each specific implementation had a get/setPropertyStr()
method that did the formatting logic.
We are now trying to move to DynaActionForm's and the logic doesn't really apply.
We subclassed DynaValidatorForm and implemented a setter for the Locale. Then we
overrode the set/get methods to detect locale parameter (endsWith("Str")) and convert
it appropriately.
This is a problem since we can't populate a property that wasn't initialized so for
every none string property we now have two version (within struts-config.xml) one as
the actual type and the otherone as a string. This is both wastefull and dumb.

Going over the struts code I noticed that struts uses the bean util convert framework
and that another version exists which seemed to support locale. However going over
the bean util code it seems that the framework is static thus preventing support for
multiple locales.

Furthermore locale is only a small part of the formatting information we need.


Usually we need patterns per locale as well.
The solution I'd like to see for dyna forms would be something like:

<form-bean name="myForm" type="myformpackage.MyForm">


<form-property name="number" type="java.math.BigDecimal"
pattern-key="res.BigDecimal" />
</form-bean>

where pattern-key represents a key in the resource bundle for number formatting (or
date formatting).

Struts Tip #13 - Use Display* helpers to convert or transform properties


Location: http://www.jguru.com/faq/view.jsp?EID=1001954
Created: Sep 20, 2002
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

There are many properties in an application that need to rendered in a particular


way. The database may store a telephone number as a simple String of numerals,
but your business requirements might say that telephone numbers must formatted
with spaces or hyphens to make them easier to read.

A good way to handle these requirements is with a helper method. The helper
method starts with the original database value and then modifies it to meet the
business requirements. Sometimes, the value may modified in more than one way.
One page may require that a person's name in all capital letters, or displayed last
name first. Using the helper pattern, we can store the original value once in our
transfer object and use helpers to modify it as needed.

Dates are another place where we can use helpers. Internally, the database may
store a date as a binary Timestamp. But when we send the date between the
business and application tiers, we would prefer to represent it as a String that the
users can view and edit.

The Artimus example application uses a contributedDisplay helper property to


render the Timestamp as a String and then convert it back to a Timestamp later. The
ActionForm just uses the String property, contributedDisplay . the business tier,
there are two properties. A Timestamp contributed property, to hold the database
value, and the String contributedDisplay helper property. Here's some code from
the *business logic* bean:

public static Timestamp getTimestamp() { return new


Timestamp(System.currentTimeMillis()); }

private Timestamp received= getTimestamp(); public Timestamp


getReceived() { return (this.received); }

public void setReceived(Timestamp received) { this.received=received; }


public void setReceivedDisplay(String receivedDisplay) { if
(null==receivedDisplay) this.received = null; else this.received =
Timestamp.valueOf(receivedDisplay); }

public String getReceivedDisplay() { Timestamp received =


getReceived(); if (null==received) return null; else return
received.toString(); }

Note that in our business logic bean (above), the receivedDisplay property has
no field of its own. It gets what it needs from the contributed property, munges the
value, and returns the desired result. the ActionForm, we have a typical String
property:

private String receivedDisplay = getTimestamp().toString();

public String getReceivedDisplay() { return this.receivedDisplay;

public void setReceivedDisplay(String receivedDisplay)


{ this.receivedDisplay = receivedDisplay; }

The business bean handles the conversion issues. The ActionForm just buffers the
String property.

Of course, the date-handling here is rudimentary but can easily improved by


changing how the business tier method is implemented. The ActionForm and JSP
code would unaffected any change in how the business tier chooses to render the
date.

The Display* helper technique can used to fill whatever data conversions or
transformations an application may require. The essence of this tip is to recognize
that data conversion and formatting is a business requirement and should handled
the business tier whenever possible.

###

HTH, Ted.

<hr>

Struts Tips are based on excerpts from the book Java Web Development with
Struts. The tips released twice weekly on the MVC-Programmers List. To subscribe,
visit BaseBean Engineering.

About Ted. Ted Husted is an active Struts Committer and co-author of Java Web
Development with Struts and Professional JSP Site Design. Ted also moderates the
Struts mailing list and the JGuru Struts FAQ.

Copyright Ted Husted 2002. All rights reserved.

Comments and alternative answers


bean:write calling getAsText() instead of toString()
Author: Nic Daniau (http://www.jguru.com/guru/viewbio.jsp?EID=881099), Nov 5,
2002
Hi Ted,

The only problem I have with this solution (unless I've completely missed the point)
is that your business layer becomes tied with your presentation layer, which is often
not a good idea. The day my boss decides telephone numbers should be displayed
with dashes instead of brackets and spaces, I idealy don't want to modify anything in
my transfer object or business bean. Therefore a method called getXDisplay
anywhere in my logic/business packages looks suspect to me.

A priori, I would expect another class (something like


"TelephoneNumberFormatForMyApplication") to do the fomatting, between my
business and presentation processes. Struts bean:write tag documents the use of a
PropertyEditor that would do just that — as far as I undestand —, format a property
from a bean. Unfortunately I've never managed to make it work properly. Would
someone be able to enlighten me on the magics of PropertyEditors and their use in a
struts context?

Thanks!

Re: bean:write calling getAsText() instead of toString()


Author: Nic Daniau (http://www.jguru.com/guru/viewbio.jsp?EID=881099), Nov
5, 2002
Now, I realize what you say at the very end memo: "data conversion and
formatting is a business requirement". But you seam to conclude from that that it
necessarily means it becomes part of the application business layer. I think part of
my question would be answered if I became conviced of this :)

If my application has several front ends, web page, wap screen and audio, am I
going to have 3 methods "getXDisplay" on my transfer objects? What happens
when I modify the way phone numbers are spoken on my audio front end, do I
have to redeploy my web and wap front ends as well?...

Nic hits the nail on the head.


Author: Joe Hertz (http://www.jguru.com/guru/viewbio.jsp?EID=1157041), Mar 24,
2004
I agree with Nic. *entirely*.

The html:text struts tags necessarily require string values, which the business objects
may not be. It's not like this need is a surprise.

If the framework itself can't deal with the conversion from String to
Date/Float/BigDecimal or whatever type (or give me a place to describe how to do the
conversion for my own objects), then it hasn't isolated me from the web tier *at all*.

The business logic should should be platform agnostic. Implemented well, it shouldn't
need a change because it has been deployed in a WebApp. If the business needs didn't
require a String Conversion to do the job, but the Web Tier does require it, then the
WebApp's Framework is falling down on the job.

Sorry to be so harsh, but I'm running into this issue right now in *spades*. I shouldnt
be having to modify my business logic to accomodate the web framework. The
business objects should be agnostic as to where the app exists. That's why they are
business objects.

Struts Tip #12 - Use smart forwarding to create menuing systems


Location: http://www.jguru.com/faq/view.jsp?EID=1001975
Created: Sep 20, 2002 Modified: 2002-11-09 19:37:55.375
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

One things that has made the World Wide Web so popular is ease of navigation. Any
swatch of text on a page can be turned into a hyperlink. The user just needs to
point-and-click, and off they go to the target page. Behind the swatch of text is a
path to the page, which may be long and cumbersome, but the user doesn't need to
know that. They just click on the description, and the system does the rest.

Besides the ubiquitous hyperlink, HTML also provides us with an assortment of user
interface widgets, like radio buttons, check boxes, and select lists. Like hyperlinks,
they allow us to display a plain language description to the user, but return a
technical descriptor to the server. Most often, these controls are used to make it
easier to fill-out a form, but they can also be used to create menu systems. The use
selects a location from the select list, and the system wisks them off to the relevant
page.

The simplest way to build a menu system would be to just embed the page locations,
or URLs, into the control. Any many, many web applications have been written using
that approach, especially those using CGI systems like Perl. But, embedding systems
paths is not the way we build appilcation with Struts. We want to design pages using
logical identifiers, and let Struts do the matching between identifers with system
paths. This way we can move things around without the pages being any the wiser.

The fundamental way Struts matches identifiers with system paths is through the
Struts configuration (struts-config.xml). Struts applications continually use the
configuration to math up ids like "success" and "failure" to various locations with the
application. Now how do the same thing to support menuing systems?

In Tip #11, we looked at our a standard RelayAction can be used to select between
multiple submit buttons. Now lets look at how we can use the RelayAction and some
other standard actions, to select between multiple options on a select list.
The simplest instance would be selecting between various locations in an application.
Here's a an example with two options

<html:select property="dispatch" >


<html:option value="reload">Reload Config</html:option>
<html:option value="create">Create Resources</html:option>
</html:select>

This controls can be used just like the multiple submit buttons in Tip #11. The form's
dispatch property is set to whatever is selected. The form is submitted to a
RelayAction with a local forward for each option. The RelayAction then forwards the
request along to whatever path is indicated by the forward.

<action
path="/menu/Manager"
type="org.apache.scaffold.struts.RelayAction"
name="menuForm"
validate="false">
<forward name="reload" path="/do/admin/Reload"/>
<forward name="createResources" path="/do/admin/CreateResources"/>
</action>

This is great for simple requests, but what if we need to include a parameter with the
action?

If the control is being used to select parameters for the same action, or actions that
use the same parameter name, you can just give the option the parameter name.
Here's a radio button control that displays identifiers like "Day" and "Week" but
passes the corresponding number of hours to the action.

<html:form action="/find/Hours">
<P>List articles posted in the last:</P>
<P>
<INPUT type="radio" name="hours" value="24">Day
<INPUT type="radio" name="hours" value="168">Week
<INPUT type="radio" name="hours" value="720">Month
</P>
<P> <html:submit property="submit" value="GO"/> </P>
</html:form>

When they submit the form, the browser will generate a URI like

/find/Hours?hours=24

or

/find/Hours?hours=168

or

/find/Hours?hours=720
depending on which radio button is selected.

In practice, we might want to write this control from a collection, using code like

<html:form action="/find/Hours">
<P>List articles posted in the last:</P>
<P><html:options collection="FIND" property="value"
labelProperty="label"/></P>
<P><html:submit property="submit" value="GO"/></P>
</html:form>

But, that would not be an instructive example. So, we show our options hardcoded
instead, even if that is not what we would do in practice.

Hardcoding a parameter, or passing it down with a collection, works fine when all our
options go to the same option, or goto actions that use the same parameter name.
But what if the parameters names are different. We may have a number of actions
for looking up a record based on this field or that field, and may need to provide the
field as the parameter name, like this:

/do/find/Title?title=Struts

/do/find/Author?creator=husted

/do/find/Content?content=menus

/do/article/View?article=12

There are many times when we would like to provide locations like these as a single
combo control, that lets us select the search type (Title, Author, Content, ID), and
then provide a user-supplied parameter, like those shown.

In each case, all we really need to do is paste the parameter to the end of the URI.
The form would still need to submit the parameter under the same name, but if we
could take something like

/do/menu/Find?dispatch=title&value=Struts

and turn it into

/do/find/Title?title=Struts

we'd be in business.

Since this is a common need, its worth creating a standard action to do just this.
Here's a the source for a simple parameter action that pastes a value at the end of a
partial URI.

// Get "dispatch" parameter


String parameter = request.getParameter(Tokens.DISPATCH);
// Get parameter name for this mapping
String paramName = mapping.getParameter();

StringBuffer path = new StringBuffer(64);

// Get stub URI from mapping (/do/whatever?paramName=)


path.append(mapping.findForward(parameter).getPath());
// Append the value passed (/do/whatever?paramName=paramProperty)
path.append(request.getParameter(paramName));

// Return a new forward based on stub+value


return new ActionForward(path.toString());

Like the Dispatch actions (see Tips #2 and #3), it needs to get the name of the
parameter from the mapping's parameter property. Here's the corresponding
mapping:

<action
path="/menu/Find"
type="org.apache.scaffold.struts.ParameterAction"
name="menuForm"
validate="false"
parameter="keyValue">
<forward name="title" path="/do/find/Title?title="/>
<forward name="author" path="/do/find/Author?creator="/>
<forward name="content" path="/do/find/Content?content="/>
<forward name="article" path="/do/article/View?article="/>
</action>

You may note that the action uses a form-bean called "menuForm". This is a simple
bean with properties common to many menu items. Here's the source:

private String keyName = null;


public String getKeyName() {
return this.keyName;
}
public void setKeyName(String keyName) {
this.keyName = keyName;
}

private String keyValue = null;


public String getKeyValue() {
return this.keyValue;
}
public void setKeyValue(String keyValue) {
this.keyValue = keyValue;
}

private String dispatch = null;


public String getDispatch() {
return this.dispatch;
}
public void setDispatch(String dispatch) {
this.dispatch = dispatch;
}

The version in the Scaffold package includes some other convenience properties, but
these three are the important ones.

Of course, your form can still use all the properties it needs. They all go into the
request and stay there for the duration. When one of the standard action forwards
the request, all the original parameters go with it. You can populate as many
ActionForms as you like from the same request. When the request arrives at the
mapping for the target action, whatever form-bean it uses is populated normally.

So far, we've looked at using the RelayAction to select between different submit
buttons or menu selections, and the ParameterAction to append a value to a query
string. There is one more action like this in our repetiorie, the FindForwardAction.

The RelayAction relies on there being a parameter with a known name in a request.
For example, [dispatch=save]. It looks for the parameter named "dispatch", then
looks for a forward named "save". The FindForwardAction is even more dynamic. It
runs through all the parameter names and checks to see if any are also the name of
a forward. If so, it returns the matching ActionForward.

This can be a good way to match multiple submit buttons without using JavasScript
to set the dispatch property. If you have buttons named save, create, and delete,
and forwards also named save, create, and delete, the FindFowardAction will
automatically match one with the other.

JSP:
<html:submit name="save">SAVE</html:submit>
<html:submit name="create">SAVE AS NEW</html:submitl>
<html:submit name="delete">DELETE</html:submit>

config:
<action
name="articleForm"
path="/do/article/Submit"
type="org.apache.scaffold.FindForwardAction">
<forward name="create" path="/do/article/Create"/>
<forward name="save" path="/do/article/Store"/>
<forward name="delete" path="/do/article/Recycle"/>
</action>

The FindForwardAction is a little mroe complicated than the others, but it still quite
brief.

for (int i=0; i<forwards.length; i++) {


if (request.getParameter(forwards[i])!=null) {
// Return the required ActionForward instance
return mapping.findForward(forwards[i]);
}
}

return null;
The only caveat here is that you have to manage your forward and control names
more carefully. The FindForwardAction will check all the parameters on the form with
all the available forwards, and the first one it finds wins. So if any of your control
names match any of your forward names, it might come up with an unexpected
match.

This can be useful when you cannot add a dispatch property to a form, or cannot use
JavaScript to set the dispatch property. But the RelayAction should be preferred
when possible, since it is more "deterministic".

Using these techiques together can fill a surprising number of your menuing needs
and keeps all the flow control within the Struts configuration.

HTH, Ted.

<hr>

Struts Tips are based on excerpts from the book Java Web Development with
Struts. The tips released twice weekly on the MVC-Programmers List. To subscribe,
visit BaseBean Engineering.

About Ted. Ted Husted is an active Struts Committer and co-author of Struts in
Action and Professional JSP Site Design. Ted also moderates the Struts mailing list
and the JGuru Struts FAQ.

Copyright Ted Husted 2002. All rights reserved.

Use optional forwarding to extend Actions


Location: http://www.jguru.com/faq/view.jsp?EID=1023579
Created: Nov 9, 2002
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

Many times you will find that two Actions are very similar but need one small
behavior to change. One good way to handle this is to subclass one Action from the
other and change the behavior that way. Though, in the case of an Action, the
behavior may buried in the perform (or execute) method. It may also not really
seem worth a hotspot method of its own.

DEFINITION hotspot - also called flexible points or extension points, hotspots are
locations where code may added to customize a framework. Hotspots (the hotspot
subsystem) describe the different characteristics of each application that can
supported by the framework. In essence, Hotspots represent the problems that a
framework solves. Many object-orientated frameworks consist of a kernel subsystem
and a hotspot subsystem. [Braga et al]

Meanwhile, the method signature is locked, and adding another parameter to change
the behavior is not trivial.

For an Action, another way to create a hotspot is through the ActionMappings. From
an architectural perspective, the ActionMappings are a red-hot extension point in
the framework. Virtually every Action in an application is designed to be extended
through the ActionMappings -- most often though use of the ActionForwards provided
by the mappings.

The vast majority of Actions include "success" or "failure" forwards or something very
much like them. The Action is often coded to use these as static parameters. Part of
the Action's API contract is that it expects such forwards to exist either locally or
globally. If they don't -- white screen: the browser returns a null response.

But we're writing dynamic applications here, and the forwards can treated as
dynamic parameters too.

One common circumstance is checking for the cancel button. Some Actions need to
do this, others do not. We could cut-and-paste the code around, but that's not the
best road to reuse.

In practice, if the cancel button is pressed, the Action needs someplace to go


anyway. So, what if the Action were to check to see if it had a "cancel" forward? If
so, it can check for the cancel button, and return the forward if the button was
pressed. If there is not a cancel forward, or the cancel button was not pressed, the
Action can just go about its business.

Here's some code that does just that:

forward = mapping.findForward("cancel");
if ((forward!=null) && (isCancelled(request))) {
// Post token error message
ActionErrors errors = new ActionErrors();
errors.add(ActionErrors.GLOBAL_ERROR, new ActionError("error.cancel"));
saveErrors(request,errors);
return (forward);
}

First, it checks to see if a "cancel" ActionForward has been defined. If an appropriate


ActionForward has been defined (!=null) and the request was in fact cancelled, a
message is posted and the "cancel" ActionForward is returned, ending the method.

If you put something like this in a base Action for your application, when you define
a "cancel" forward that leads to another action, you may need to define it as a
redirect.

<forward
name="cancel"
redirect="true"
path="/do/Menu"/>

The redirect will clear the cancel state. If the other action is checking for cancel too,
this will keep you from falling into a loop. Of course, if the other Action doesn't check
for cancel, then using redirect isn't important. But code like this gets the most reuse
when it's provided through a base Action that your other Actions subclass.

Another good example is whether to use a transaction token with an operation. The
token code is not complex, but it would nice if we did not have to copy and paste it in
wherever we needed it. It would nicer still if we could look at the configuration file
and tell whether a Action wanted a token or not.

// Check for missing token


forward = mapping.findForward("getToken");
if ((null!=forward) && (!isTokenValid(request))) {
// Post token error message
ActionErrors errors = new ActionErrors();
errors.add(ActionErrors.GLOBAL_ERROR, new ActionError("error.token"));
saveErrors(request,errors);
return (forward);
}
if (null!=forward) {
// reset to guard against duplicate request
resetToken(request);
}

So, if the ActionMapping for an Action using this code includes a "token"
ActionForward,

<forward name="getToken" path="/pages/error.jsp"/>

and the token is missing or invalid, it will forward to the "getToken" page instead of
processing the rest of the Action. If the was a "token" forward, but it was valid, the
code resets the token so it can't used again.

To close the loop, we can include a "setToken" forward to tell an Action to create a
new token.

// Check for save token directive (do this last)


forward = mapping.findForward("setToken");
if (null!=forward) saveToken(request);

Though, this is really a kludge, since the ActionForward URI would never used, and
so we are misusing its role in the framework. A better approach would to extend
ActionMappings to tell the Action whether to create a token or not,

if (myMapping.setToken()) saveToken(request);

but that's more surgery than we can squeeze into a tip =:0)

HTH, Ted.

-----

Struts Tips are based on excerpts from the book Struts in Action. The tips released
weekly on the MVC-Programmers List. To subscribe, visit BaseBean Engineering.

About Ted. Ted Husted is an active Struts Committer and co-author of Struts in
Action and Professional JSP Site Design. Ted also manages the JGuru Struts FAQ and
moderates the Struts mailing list.
Comments and alternative answers

I used the code for redirecting the action when the cancel button is pressed as
shown in the example above but the error message is not displayed
Author: Brian David (http://www.jguru.com/guru/viewbio.jsp?EID=1052394), Mar 1,
2003
I"m not sure if I understand the lifecycle of the request correctly. In the example
above the ActionErrors are placed in the request, but the forward defined for cancel
uses a redirect. Wouldn't this clear the request context and thus the ActionErrors
Object that was placed there in the preceeding line of code? If not can someone please
explain the life cycle of the request in this case. Thanks, Brian

Is that possible?
Author: V Khin (http://www.jguru.com/guru/viewbio.jsp?EID=1103157), Jul 22,
2003
Is there a way to obtain an ActionForward without having a reference to an
ActionMapping?

Thx!

An example using ejbs with struts Any examples(in books, links, articles et
al) providing usage of ejbs with struts out there? I know it is possible and
would be a good arch..but have not seen a single example to-date using the
two.
Location: http://www.jguru.com/faq/view.jsp?EID=1023583
Created: Nov 9, 2002
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by neal ravindran PREMIUM
(http://www.jguru.com/guru/viewbio.jsp?EID=17737

Chapter 13 in the upcoming book, Mastering Jakarta Struts, with an example of a


application that uses Struts and EJBs. There's a draft available online:
http://www2.theserverside.com/resources/strutsreview.jsp This hasn't been posted
here yet, but here's an upcoming Tip on using EJBs with Struts:
http://husted.com/struts/tips/018.html -Ted.
Comments and alternative answers

An example using ejbs with struts


Author: Craig Jackson (http://www.jguru.com/guru/viewbio.jsp?EID=1029612), Nov
24, 2002
I don't think struts dictates how and where you utilise ejb's.

For example, you can locate and invoke an EJB entirely from within an Action you
have defined. Probably not a good practice though.

You could alternatively have your Action instantiate a Business Delegate (refer Sun's
core J2EE patterns), which (a) uses a Service Locator (refer again Sun's core J2EE
patterns) to locate and instantiate the EJB's and (b) provides accessor and mutator
methods which invoke the required EJB methods etc.

Re: An example using ejbs with struts


Author: James Ketterer (http://www.jguru.com/guru/viewbio.jsp?EID=1140147),
Jan 20, 2004
Struts Kick Start from Sams publishing has a good example usint Struts, Session
EJB using Tomcat and JBoss. The only thing is you have to learn another tool
called XDoclet which was pretty involved.

Devx site
Author: Stephen Lum (http://www.jguru.com/guru/viewbio.jsp?EID=1167886), May
20, 2004
http://www.devx.com/Java/Article/21065/

== struts-config.xml: Is it possible to ... == Hi

Is it possible in the struts-config.xml to configure action mappings for


simple JSP<->Servlets relations. a.k.a I have pages that don't make use of
any form thus they don't need struts ... But I wonder if there is a way to
configure simple JSP<->Servlets mapping (WITHOUT actionForm or bean
form) - How do you do you guys???

Thanks!
Location: http://www.jguru.com/faq/view.jsp?EID=1023586
Created: Nov 9, 2002
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by joey corleon PREMIUM
(http://www.jguru.com/guru/viewbio.jsp?EID=950126

You can use the forward property to associate a JSP or some other resource to the
mapping path.

<action
path="/Menu"
forward="/pages/Menu.jsp"
/>

As a rule, most Struts architects recommend putting all the JSPs behind an
ActionMapping, whether they use an Action or not. This puts a layer of security in
front of your JSPs and makes it easier to migrate to "modules" in Struts 1.1.

You can also refer to other servlets in the same way, so long as they have been
mapped to a URI.

HTH, Ted.
Comments and alternative answers

How to prevent direct access?


Author: Daniel Rabe (http://www.jguru.com/guru/viewbio.jsp?EID=1129037), Nov
18, 2003
I'd like all my JSPs to go through the servlet so that I can have my authentication code
in one place. (I currently extend RequestProcessor and override processPreprocess. If
the session hasn't been authenticated, I redirect to a login page.) What's to prevent a
user from typing in an URL that goes directly to the JSP (in this example,
../pages/Menu.jsp)?

Re: How to prevent direct access?


Author: Santeri Salminen
(http://www.jguru.com/guru/viewbio.jsp?EID=1144652), Feb 9, 2004
You probably have something like this in your web.xml:
<servlet-mapping>
<servlet-name>MyApplication</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
Replace *.do with * in order to map everything to the controller servlet.

Re: How to prevent direct access?


Author: Jens Møller (http://www.jguru.com/guru/viewbio.jsp?EID=442059), Jul
8, 2004

You could put all your protected jsp pages somwhere in the WEB-INF directory
(ie. WEB-INF/jsp/), this way they will only be accessable from servlets or other
jsp pages.

Some people recommend against this procedure, since it may not be supported by
all servlet/jsp engines.

Struts-config.xml
Author: Vijendra Singh
(http://www.jguru.com/guru/viewbio.jsp?EID=1255652), Jul 29, 2005
Hi i am facing problems while using struts in my jsp pages.All configuration
settings are ok.Tomcat4.1 or 5.0 both i am using.Even Weblogic 8.1 having
struts inbuild.But while building application i am facing errors.can Somebody
post any struts-config.xml file with usage of ActionForms,ActionClasses,Jsp
pages.Complte flow of program. Any suggestions will be appreciated. Vj

Dynamic values for hidden fields I'm trying to set the values of hidden fields
dynamicly, eg: <form:hidden property="employeeName" value="<%=
employeeBean.getName() %>" /> I get compile errors - how can I do this?
Location: http://www.jguru.com/faq/view.jsp?EID=1023589
Created: Nov 9, 2002
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by Charl Gerber
(http://www.jguru.com/guru/viewbio.jsp?EID=976214

In this case, I'd ditch the form:hidden and just write the tag this way:

<input type="hidden" name="employeeName" value="<bean:write


name="employeeBean" property="name"/>">

HTH, Ted.

Comments and alternative answers

The bean:write tag inside value is not being resolved


Author: Artur de Sousa Rocha (http://www.jguru.com/guru/viewbio.jsp?EID=70489),
Mar 17, 2003
The bean:write tag inside value is not being resolved; it is only entity-escaped. You
must either cast employeeBean to its type and only then apply the getName method,
or you may first create a new bean containing name with a bean:define tag and then
replace "employeeBean.getName()" with it (possibly wrapping around with
String.valueOf()):
<bean:define id="emplName" name="employeeBean" property="name"/>
<html:hidden property="employeeName" value="<%=emplName%>"/>
More details: The bean:define tag puts a bean called emplName into the page scope
(accessible with tags like bean:write) and creates a local variable with the same name.
In your case it is a String so it doesn't need to be wrapped in String.valueOf().

Re: The bean:write tag inside value is not being resolved


Author: Sreekanth Bhaskaran
(http://www.jguru.com/guru/viewbio.jsp?EID=1185498), Jul 12, 2004
In Ted's answer above, it is given: value="<bean:write name="employeeBean"
property="name"/>" value should be enclosed in single quotes and not double
quotes. value='<bean:write name="employeeBean" property="name"/>' It will
work. Courtesy: Ted's own Struts book.

Re[2]: The bean:write tag inside value is not being resolved


Author: Eric Lennon Bowman
(http://www.jguru.com/guru/viewbio.jsp?EID=1206564), Oct 21, 2004
That doesn't work, it still entity-escapes it. <input type="hidden"> seems (to
me) to be the cleanest way.

Re: The bean:write tag inside value is not being resolved


Author: Anand Agrawal (http://www.jguru.com/guru/viewbio.jsp?EID=1246582),
May 31, 2005
I tried using this piece of code and it didn't work. This is what I did:

<bean:define id="categoryId" name="categoryDto" property="categoryId"/>


<html:hidden property="categoryId" value="<%=categoryId%>"/>

This is the error I got: "JavaCompile: The method setValue(java.lang.String,


java.lang.Object) in the type javax.servlet.jsp.tagext.TagSupport is not applicable
for the arguments (java.lang.Object)."

I had set the categoryDto in the Action Class using request.setParameter

Any idea why it didn't work?

Re[2]: The bean:write tag inside value is not being resolved


Author: swami dorai (http://www.jguru.com/guru/viewbio.jsp?EID=1259824),
Aug 26, 2005
id="categoryId" is an Object. You need to convert it to maybe String, it will
work. <html:hidden property="categoryId"
value="<%=(String)categoryId%>"/>

iterate + link with 2 request parameters I have a bean with a collection of


states and postal codes. I want to do something like this:

<logic:iterate>
<a href="detail.do?state=beanstate[i]&postal=postalcode[i]"> Detail
i</a>
</logic:iterate>

But i would like to do it using <html:link> tag. How can I set 2 request
parameters (I think I need a HashMap) if my link is between <logic:iterate>
and </logic:iterate>?

Thanks.
Location: http://www.jguru.com/faq/view.jsp?EID=1023734
Created: Nov 10, 2002
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by Guido García
(http://www.jguru.com/guru/viewbio.jsp?EID=1011381

Yes, create a map with the properties and values that you would like to pass as
properties, and place it in request scope. You can then refer to it via the name
parameter to link. For a list, create a collection of maps.

<logic:iterate name=links" id=link">


<html:link page="/detail.do" name="link"/>
</logic:iterate>

HTH, Ted.
Comments and alternative answers

Nested Iterate + link with n request parameters


Author: Francis Tran (http://www.jguru.com/guru/viewbio.jsp?EID=1029407), Nov
22, 2002
Hi Ted,

How would you do this with nested:iterate tag instead? That's it, passing the
1levelProperty.2levelProperty.etc.. as request parameters within the nested:iterate tag
and using nested:link?

I tried to use paraName="location" where location is defined in my struts-config.xml


as one of the form-bean and is the same object has nested-iterate is iterating over.

This doesn't seemed to work as I used <logic:present> to verify if object "location" is


presence or not.

any thoughts?
Many thanks,
Francis

Struts Tip #15 - Use chained exceptions


Location: http://www.jguru.com/faq/view.jsp?EID=1026405
Created: Nov 16, 2002
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

Many Java mavens recommend that business objects throw their own exceptions.
Internally, a component may catching a SQL or IO exception, but what we really
need to tell the user is that a data access error occurred. Of course, at the same
time, you do not want to sacrifice any detail from the original exception. Retaining
detail from the exception can especially important in a layered, multi-tiered, or multi-
platform application.. The business component may not have direct access to the log,
and the exception is its only way of telling us what went wrong.

In short, we need a way to keep the detail of the original message but at the same
time also add a user-friendly business exception. The former may complain that it
could not process a SQL query. The latter may simply report that a "data access
error" occurred and suggest that you contact the database administration. We would
also want to sure to log both exceptions, to sure all the detail is maintain some
actually contact a DBA.

As the exception class was originally designed, doing something like this is a
problem. The Java exception mechanism allows you to throw only throw one
exception, not two or three. It's easy to "wrap" exceptions, using one to initialize the
next, but that results in loss of detail over multiple layers. What we really need to do
is "stack" or "chain" the exceptions, so that each layer can add its own viewpoint to
the incident. Then, at the end, display them all, with the originating exception at the
bottom of the list.
This approach works surprisingly well in a layered architecture. The "topmost" layer
is "closest" to the user, and so throws the most "user-friendly" exceptions. The
"lowest" layer throws the "geek-friendly" errors that we need to solve the problem.
When we chain exceptions by linking them together, the user-friendly message
comes first, followed by the more detailed messages. The user is told what they need
to know first, and can leave the rest to the system administrators.

The best part is that chaining exceptions is very easy to implement in Struts!

Java 1.4 provides new functionality for chaining exceptions, but it is not difficult to
write your own ChainedException class for using with another JVM. The Scaffold
package, currently bundled with Artimus, includes a ChainedException class that
works with older JVMs.

Here's a try/catch block from a base Action that uses the Scaffold ChainedException
class. It calls a member method to perform the business operation and then analyzes
the result.

// (1)
ActionErrors errors = new ActionErrors();
try {
executeLogic(mapping,form,request,response);
}
catch (Exception exception) {
// (2)
servlet.log("*** ACTION EXCEPTION: ", exception);
exception.printStackTrace();
// (3)
errors.add(ActionErrors.GLOBAL_ERROR, new
ActionError("error.general"));
// (4)
StringBuffer sb = new StringBuffer();
if (exception instanceof ChainedException) {
ChainedException e = (ChainedException) exception;
e.getMessage(sb);
}
else {
sb.append(exception.getMessage());
}

// (5)
errors.add(ActionErrors.GLOBAL_ERROR, new
ActionError("error.detail",sb.toString()));

} // end catch
// (6) ... branch to error page if errors are not empty

(1) We setup an empty ActionErrors collection for later use, call the business
operation, and catch any and all exceptions it might throw.

(2) If an exception is thrown, we start by logging the message and including a


marker so that it is easier to find later. We also print the stack trace, to sure that is
recorded for future reference.
(3) We start by adding our own general error message to the errors collection. This
just says something like "The process did not complete. Details should follow."

(4) If the business operation passes back a subclass of ChainedException, we trundle


through the chain, and collect all the messages.

(5) To make the messages easy to display a presentation page, we wrap them in a
generic message template. The message template is a single substitution code,

error.detail={0}

so that it just prints everything verbatim.

The end result is a series of error messages like

* A required resource is not available.


* The process did not complete. Details should follow.
* Cannot connect to MySQL server localhost:3307. Is there a MySQL server running
the machine/port you are trying to connect to? (java.net.ConnectException)

being

1. The business object message.


2. The general error message.
3. The original message from the JDBC driver.

An advantage to this approach is that it provides a high-level message for the user
("A required resource is not available.") and a low-level message for technical
support ("Cannot connect to MySQL server ..."). So, everybody's happy! The user
gets a reasonable message. Support gets the detail needed to solve the problem.

-----

Struts Tips are based on excerpts from the book Struts in Action. The tips released
weekly on the MVC-Programmers List. To subscribe, visit BaseBean Engineering.

About Ted. Ted Husted is an active Struts Committer and co-author of Struts in
Action and Professional JSP Site Design. Ted also manages the JGuru Struts FAQ and
moderates the Struts mailing list.

Copyright Ted Husted 2002. All rights reserved.

testing a struts application i wan't to test a struts-application

can somebody tell me whats the best way to do this?

i'm thankfull for any solution


Location: http://www.jguru.com/faq/view.jsp?EID=1027548
Created: Nov 19, 2002
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by Jan Thomas
(http://www.jguru.com/guru/viewbio.jsp?EID=1019885

There are some unit tests included with the Struts source distribution (nightly build).

The Struts TestCase is also quite good.

The MockObject site also has some bood material on testing applications, including
web applications.

The Cactus site at Jakarta provides good coverage of testing web applications, both
in container and through conventional JUnit tests.

HTH, Ted.

Comments and alternative answers

testing Struts
Author: Steve Carter (http://www.jguru.com/guru/viewbio.jsp?EID=1029438), Nov
22, 2002
I have tested some large scale struts applications and here is what I learned:
1) if the app is a fairly decent size its debatable writing automated tests for the UI
verse just manually verifying the UI functions and displays correctly
2) automate tests from the struts layer back. the basic approach was as follows:
-- write unit tests using the JUnit test framework. (JUnit.org) There may be extensions
now for struts. The basic idea was to test the actions by invoking the perform/execute
method of the Action from the test class. The parameters passed to the action were all
Mocked by writing a class which extended the appropriate classes and over ride the
methods you need to in order to set up state for the test.
For example, testing LogonAction I would have a unit test class which calls the
perform/execute method with an ActionForm form with the appropriate fields,
username and password, populated. I would have mocked out the request and session
classes and implemented the set/get attribute and parameter methods using hashtables.
I would set the expected parameters and then invoke. Once the perform method was
finished I would then assert that the state of the form object was populated with the
values in the DB that are for the user that logged in (that is what the result of a
succesful login would be) Also, I automate the insertion and deletion of test data in
the DB. this way I can test error cases where I can try to login as an invalid user and
then check the struts Error object to see if it contains the correct message. Hope this
helps.

Struts Tip #16 - How to (not) check a radio button


Location: http://www.jguru.com/faq/view.jsp?EID=1028442
Created: Nov 21, 2002
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

Each radio button element requires an assigned value that distinguishes it from the
other radio buttons. When creating a static array of radio buttons, you need to
indicate which one of these, if any, is checked. This does not need to be done when
the radio buttons are being populated from dynamic data. The control can compare
itself to the form bean's property and then check itself when appropriate.

Given a set of <html:radio> controls like this:

<html:radio property="expectedVia" value="UPS"/>UPS


<html:radio property="expectedVia" value="FEDX"/>Federal Express
<html:radio property="expectedVia" value="AIRB"/>AirBorne

And that the expectedVia property on the form bean was already set to "UPS", then
the HTML radio elements would be rendered like this:

<input type="radio" name="expectedVia" value="UPS"


checked="checked">UPS
<input type="radio" name="expectedVia" value="FEDX">Federal Express
<input type="radio" name="expectedVia" value="AIRB" >AirBorne

If you need to create a dynamic set of radio buttons, or want to localize the values,
you can create in an Action a collection of LabelValueBeans with the appropriate
labels and values for each button. Here's an example:

ArrayList shippers = new ArrayList();


shippers.add(new LabelValueBean("UPS", "UPS"));
shippers.add(new LabelValueBean("Federal Express", "FEDX"));
shippers.add(new LabelValueBean("AirBorne", "AIRB"));
request.setAttribute ("SHIPPERS",shippers);

Then, on the page, you can iterate through the collection

<logic:iterate id="row" name="SHIPPERS"


type="org.apache.commons.scaffold.util.LabelValueBean">
<html:radio property="expectedVia" value="<%=row.getValue()%>"/>
<bean:write name="row" property="label"/>
</logic:iterate>

So long as one of the values matches the "expectedVia" property on our ActionForm,
the radio tag will still automatically select the appropriate button.

In Struts 1.1, you can use the built-in LabelValue class instead
[org.apache.struts.util.LabelValueBean].

Struts 1.1 (beta 2 or later) also provides an additional property to the RadioButton
tag that eliminates the need to use a scriplet. With 1.1, we can interate through the
same collection this way:

<logic:iterate id="row" name="SHIPPERS">


<html:radio property="expectedVia" value="value" idName="row"/>
<bean:write name="row" property="label"/>
</logic:iterate>
This tells the tag to look for a bean named row, and call its getValue method, which
is what the scriplet did.

HTH, Ted.

Say, why does Struts output "checked=checked" rather than something like
"checked=true" or just "checked"? To retain XHMTL compatiblity, Struts outputs all
properties in a "property=value" format. When doing this for properties that can be
present or not (checked, nowrap, et al), the HTML 4.01 specification says to use the
same token for the property and the value. So that's what Struts does =:0) For full
XHMTL compatability, set xhtml="true" in the Struts <html:html> tag.

-----

Struts Tips are based on excerpts from the book Struts in Action. The tips released
weekly on the MVC-Programmers List. To subscribe, visit BaseBean Engineering.

About Ted. Ted Husted is an active Struts Committer and co-author of Struts in
Action and Professional JSP Site Design. Ted also manages the JGuru Struts FAQ and
moderates the Struts mailing list.

Copyright Ted Husted 2002. All rights reserved.

Comments and alternative answers

How to chek first as default anyway?


Author: Artur de Sousa Rocha (http://www.jguru.com/guru/viewbio.jsp?EID=70489),
Dec 20, 2002

Suppose I have a list of automatically generated items. How can I cause the first radio
button whatever its value to be checked? I could pre-set the appropriate property of
the form bean (assuming that I use an action to populate the items collection), but is
there a simpler way?

Already verified: By default, most browsers just don't check any radio button if not
requested. Using html:form's focus property (together with html:radio's onfocus)
doesn't help either since for multiple form elements with the same ID the Struts focus
mechanism doesn't work.

Re: How to chek first as default anyway?


Author: Elmo Malmo (http://www.jguru.com/guru/viewbio.jsp?EID=1186834),
Jul 18, 2004

I'm not a struts expert so I can't suggest a better way of preseting a radio button to
value other than to preset the value in the form bean.
I'm going to pick up on the "...since for multiple form elements with the same
ID..." part though. To have multiple elements in your (X)HTML page with the
same value for their id is bad thing. Ids are meant to be unique in a page. If you
keep your ids unique then the onfocus aproach you describe above may work as
well. Win-win situation?

Incidentally, if your using the ids to apply a certain style across a number of
elements, use the class attribute instead, that's what it's for.

Re[2]: How to chek first as default anyway?


Author: murali dhar (http://www.jguru.com/guru/viewbio.jsp?EID=1228074),
Mar 1, 2005
would u plz , explain it . Since i m using unique form ids only . But then its not
working....

Struts Tip #17 - Don't settle for <html:error/>


Location: http://www.jguru.com/faq/view.jsp?EID=1029711
Created: Nov 24, 2002
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

Many Struts applications can get by with a simple

<html:error/>

tag at the top of a page. If any error messages are present, it's this tag's job to print
them all out. To help prettify the output, <html:error> checks for errors.header and
errors.footer messages in the application resources. If found, the tag prints these
before and after the block of messages. A common setup is:

errors.header=<UL>
errors.footer=</UL>

Struts 1.0 developers can then include <LI> and </LI> tags with the text of each
message to used this way. In Struts 1.1, the situation improves with the addition of
the errors.prefix and errors.suffix messages. Just as the header and footer print
before and after the block of messages, the prefix and suffix print before the
individual messages. So to print a simple list of any message that might arise, you
can just include

errors.header=<UL>
errors.footer</UL>
errors.prefix=<LI>
errors.suffix=</LI>

in your application resources, and the (Struts 1.1) <html:error> tag will take care of
the rest.
Though, many purists would complain that HTML markup has no place in a message
resources file. And they would right. Even with the Struts 1.1 prefix and suffix
feature, you may still need to use different markup different pages.

For Struts 1.0 applications, the Struts Validation extension (see the Struts Resource
page) offers a useful alternative to the standard <html:error/> tag. You can use
these tags whether you are using the rest of the validator package or not. Instead of
providing one omnibus tag, the validator approach is to use an iterator to expose
each message, and then leave it up to the page to provide whatever other formatting
is necessary. Here's an example:

<validator:errorsExist>
<UL>
<validator:errors id="error">
<LI><bean:write name="error"/></LI>
</validator:errors>
</UL>
</validator:errorsExist>

In Struts 1.1, these tags were adopted into the core taglibs. Here's the same
example using the Struts 1.1 rendition.

<logic:messagesPresent>
<UL>
<html:messages id="error">
<LI><bean:write name="error"/></LI>
</html:messages>
</UL>
</logic:messagesPresent>

This is all great if you just want to print your messages as a batch. But many
messages are related to data-entry validation and involve a specific field. Many page
designs expect a message concerning a field to printed next to a field.

Not a problem. When the error message is queued, you can specify a "property" to
go with it. If you don't specify a property (using any of the tags we described), then
all the messages print. If you do specify a property, then only the messages queued
for that property print.

The default code for queuing an error message is:

errors.add(
ActionErrors.GLOBAL_ERROR,
new ActionError("error.username.required")
);

To specify that this message is for the "username" property, we would code this
instead:

errors.add(
"username", new ActionError("error.username.required"));
If we specify a property, we can use the <html:errors/> tag (or any of the
alternatives) like this:

<P>Username: <html:text property="username"/></P>


<P>Password: <html:password property="password"/></P>

The "username" errors print next to the username field, and any "password" errors
print next to the password field.

But what if you need to print both specific and general errors?

Again, no problem. You can also specify the "generic" property just like you did in the
Java code. First, at the top of your JavaServer Page import the Action and
ActionErrors package so you can reference the appropriate constants:

<%@ page import="org.apache.struts.action.Action" %>


<%@ page import="org.apache.struts.action.ActionErrors" %>

Then in the tags, use a runtime expression to specify the constants:

<logic:present name="<%=Action.ERROR_KEY%>">
<P><html:errors property="<%=ActionErrors.GLOBAL_ERROR%>"/></P>
</logic:present>

Viola! Specific messages print out in specific places, and any "general" errors can still
print out in a place of their own.

Of course, you don't have to settle for any of these standard tags. If these variations
still don't meet your specific needs, take a peek at the source code and cobble up
your own! The framework provides the queue, but how it prints is up to you.

HTH, Ted.

-----

Struts Tips are based on excerpts from the book Struts in Action. The tips released
weekly on the MVC-Programmers List. To subscribe, visit BaseBean Engineering.

About Ted. Ted Husted is an active Struts Committer and co-author of Struts in
Action and Professional JSP Site Design. Ted also manages the JGuru Struts FAQ and
moderates the Struts mailing list.

-----

Copyright Ted Husted 2002. All rights reserved.


Comments and alternative answers

something missing
Author: Erik Hatcher (http://www.jguru.com/guru/viewbio.jsp?EID=405274), Nov
25, 2002
This is good advice - <html:errors/> by itself is not good. :)

The example where you show specific error messages for the fields is missing the
<html:errors property="..."/>. Perhaps this is a case of mangled HTML posting?

Also, I recommend creating a custom taglib rather than using scriptlets in JSP. And in
this particular case, I created a tag that displays field labels, with a trailing asterisk if
the field is required (by Validator) and turns the label red if validation errors have
occurred.

Re: something missing


Author: Gangadhar Nataraja
(http://www.jguru.com/guru/viewbio.jsp?EID=1022833), Dec 19, 2002
Eric, I have to change the Label to Red & insert "->" before the label to indicate
the error in the field.I would appreciate if you can send me the code to
gangadhar_1973@yahoo.com Thanks, Gangadhar

Re[2]: something missing


Author: Erik Hatcher (http://www.jguru.com/guru/viewbio.jsp?EID=405274),
Dec 19, 2002
Here is a link to where I posted the relevant code to the struts-dev list:
http://marc.theaimsgroup.com/?l=struts-dev&m=103467140124965&w=2

Trouble Propagating Messages using ProcessResult


Author: Alex Honor (http://www.jguru.com/guru/viewbio.jsp?EID=1052073), Jan 30,
2003
I have followed some of the Artimus application patterns, using scaffold ProcessBean
and ProcessResult. I would like to add messages (presumably using the ProcessResult
addMessage() operation) and display these messages in my JSP. I have set a message
using message keys, defined them in the app resources and have added the
html:messages/bean:write tags in the JSP but I am unable to get messages propagated
from the ProcessBean to JSP layer. What is the recommened way of using
addMessage(). What about routing ActionErrors from inside a ProcessBean to JSPs?
Thanks

Validation.xml
Author: Michelle Rhein (http://www.jguru.com/guru/viewbio.jsp?EID=1146158), Feb
24, 2004
Could you pls explain how I would be handling this, if my error messages are
generated from my validator-rules.xml? Thanks.

Re: Validation.xml
Author: Harish P (http://www.jguru.com/guru/viewbio.jsp?EID=1138221), Aug 4,
2004
I'm facing the same problem. How can i display message beside the field (which
failed validation), when i'm using Struts validator and my validations are driven
by validator-rules.xml and validation.xml?

Listing specific errors: example incomplete?


Author: Scott Burkhalter (http://www.jguru.com/guru/viewbio.jsp?EID=1213405),
Nov 28, 2004
The example for outputting field specific errors...

To specify that this message is for the "username" property, we would code this
instead:

errors.add("username", new ActionError("error.username.required"));

If we specify a property, we can use the <html:errors/> tag (or any of the alternatives)
like this:

<P>Username: <html:text property="username"/></P>


<P>Password: <html:password property="password"/></P>

The "username" errors print next to the username field, and any "password" errors
print next to the password field.

well... wouldn't this be incomplete without the actual outputting of the generated
errors? i.e.,

<P>Username: <html:text property="username"/> <html:errors


property="username"/></P>
<P>Password: <html:password property="password"/> <html:errors
property="password"/></P>

Struts Tip #18 - Use EJBs with care


Location: http://www.jguru.com/faq/view.jsp?EID=1032045
Created: Nov 28, 2002
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

Enterprise JavaBeans (EJBs) are designed to represent the model layer of an


application. Developers often choose EJBs when building applications that will be
distributed over several servers. Many developers also like to use EJBs because of
the transparent way they handle transactions. Used properly, EJBs can be a good fit
with Struts.

Whether or not to use EJBs for a given application is a complex question. EJBs can
provide an application a plethora of services that developers might otherwise have to
write themselves. But there is no free lunch. Most developers will agree that EJBs are
a good choice for distributed, enterprise-scale applications. But most applications do
not fit in that category. Be sure to think carefully before deciding to use EJBs with
your application. Although, if your application is well designed, you should be able to
switch to EJBs, or to any model layer, without affecting the rest of your application.
The most flexible approach is to use the "facade" pattern to create a buffer zone
between the Struts Actions and your model (which includes the EJBs). To Struts, the
facade looks and acts like the actual model. In practice, the facade is talking to other
components which do the actual work.

DEFINITION - A Facade substitutes the interfaces of a set of classes with the interface
of a single class. Facade hides implementation classes behind one interface. [Design
Patterns by Gamma et al]

The ProcessBeans in the Jakarta Commons Scaffold package are an example of the
facade pattern. To switch an application from plain-vanilla JDBC to something else,
like EJBs, you can implement the business logic within a ProcessBean. The Action can
continue to call the ProcessBean without knowing anything about EJBs, JDBC, or
whatever else. (Of course, there is nothing special about ProcessBeans. Any similar
object of your own creation will work as well.)

Using a facade to encapsulate calls to your business model is called the Business
Delegate pattern.

DEFINITION- The Business Delegate hides the underlying implementation details of the
business service, such as lookup and access details of the EJB architecture. [J2EE
Design Patterns by * et al]

The Business Delegate pattern is often used with an EJB pattern called Session
Facade.

Session Facade

The classic facade pattern is also the basis of the popular "Session Facade" pattern
[J2EE Design Patterns]. Here, an EJB component called a "session bean" is used to
implement the facade. If your application is wedded to EJBs, you might choose to
have the Actions call your Session Facade directly. This will bind your Action to EJB
Session Beans, but eliminates the need to build a generic facade between the Struts
Action and your Session Facade. Like many implementation decisions, the best
choice will depend on the circumstances.

Data Transfer Objects

To display the result of an operation, it is technically possible to pass an EJB to the


presentation layer. The Struts Tags or Velocity View Tools can display the properties
of an EJB, the same as any JavaBean. However, there is some overhead to every call
to an EJB. Consequently, most developers use another object to carry data between
layers. Such carriers are called Data Transfer Objects (DTOs). The Scaffold ResultList
class is an example of a data transfer object.

The Struts ActionForm is also a type of DTO. When displaying data on the
presentation layer, you have the option of populating an ActionForm from an EJB DTO
or using the DTO directly. The deciding point is often how much control you have
over the DTO. If you can control the DTO properties, then for displaying read-only
data, you might as well pass the DTO back. The Struts tags and Velocity View Tools
work by reflection. So long as the property names match, any object type can be
used.

Of course, for input, you should use a Struts ActionForm. Once validated, the
ActionForm can be used to populate the EJB DTO. The DTO is then passed through
the facade to the EJBs.

A popular tool for working with EJBs is XDoclet. This component starts out as an
enhancement to the standard JavaDoc tool and ends up as a very clever code
generator. You can use it to create and maintain much of the bullwork code needed
by most EJB applications, including Data Transfer Objects.

Another EJB tool to pursue is the Struts-Expresso framework. Expresso supports


creating application with or without Enterprise JavaBeans, making it easier to hedge
your bets.

Implementation patterns

For the best scalability, many Struts/EJB developers follow this pattern:

• Recreate the reference to the remote interface as required.


• Use stateless session EJBs in preference to stateful EJBs.
• Avoid retaining a handle to the stateless EJBs.
• Avoid interacting directly with entities.
• Use a stateless facade that returns a data transfer object to the Action.

A discussion of the technologies behind EJBs (stateless versus stateful and so forth)
is beyond the scope of this article. For more about the Enterprise JavaBean
technology, we recommend Mastering Enterprise JavaBeans by Ed Roman et al. A
good online article is "Enterprise Bean Best Practices".

-----

Struts Tips are based on excerpts from the book Struts in Action. The tips released
weekly on the MVC-Programmers List. To subscribe, visit BaseBean Engineering.

About Ted. Ted Husted is an active Struts Committer and co-author of Struts in
Action and Professional JSP Site Design. Ted also manages the JGuru Struts FAQ and
moderates the Struts mailing list.

Copyright Ted Husted 2002. All rights reserved.

How to open a new browser window with new new page from action class.
Very Very urgent Hi: I am using struts and tiles framwork for my
application. I have a confirmation page where i am submitting the request.
In action class after successful submit, i need to print a receipt in new
browser and at the same time old browser need to be populated with fresh
entry screen. If i use javascript in entry sreen, i can't refresh form been.
beacuse same bean is being used for receipt printing. Since i am using tiles i
do not have controll over a form load methods to execute javascripts. I need
some way in jsp or action class after successful submit to make a new
request to the new jsp which opens in new browser window. This is very
important please reply to this.
Location: http://www.jguru.com/faq/view.jsp?EID=1034504
Created: Dec 5, 2002
Author: Sébastien Da Ros (http://www.jguru.com/guru/viewbio.jsp?EID=1028046)
Question originally posed by Kavitha Penchikala
(http://www.jguru.com/guru/viewbio.jsp?EID=1031341

Hi

You can open a new window, every time you submit your form, to do this just add an
attribute to your form tag, like this:
<html:form action="/client.do" target="_blank">

Seb

Comments and alternative answers

Programattically invoke Action's execute()


Author: Marilyn Perna (http://www.jguru.com/guru/viewbio.jsp?EID=5464), Feb 4,
2004

The primary requirement this user needed was a new request to the new jsp ...
moreso than which opens in new browser window.

Anyone know how to programatically submit a form to an Action once you have sent
the ActionForward?

I have just such a need. Once the user clicks a particular button, I need to return a pdf
file. I also need to disable the button on the underlying form. There is no way to send
two responses to the browser. Therefore, how can one programattically invoke an
Action's execute() method?

Re: Programattically invoke Action's execute()


Author: Ritesh Sharma (http://www.jguru.com/guru/viewbio.jsp?EID=1150191),
Feb 29, 2004
Hi!
Even i have a similar requirement. I need to return a pdf file to the browser and
also display some warnings (if any). I can put the warnings in as ActionErrors but
they will not be displayed because i can't have any action forward. (i have to set it
as null, since i am passing the pdf file in response).
Is there any way to send two responses to the browser?...how do i go about this?
Any help will be appreciated...It's kind of urgent
Thanx

Re[2]: Programattically invoke Action's execute()


Author: Latha Rao (http://www.jguru.com/guru/viewbio.jsp?EID=1157483),
Sep 27, 2004
I have a similar requirement where I need to display results in a new window.

I cannot use target="_blank" as any validation errors show up in the new


window.

Did you find a solution to your problem?

Re: Programattically invoke Action's execute()


Author: Latha Rao (http://www.jguru.com/guru/viewbio.jsp?EID=1157483),
Sep 27, 2004
I have a similar requirement where I need to display results in a new window.

I cannot use target="_blank" as any validation errors show up in the new


window.

Did you find a solution to your problem?

Re: Programattically invoke Action's execute()


Author: Latha Rao (http://www.jguru.com/guru/viewbio.jsp?EID=1157483),
Sep 27, 2004
I have a similar requirement where I need to display results in a new window.

I cannot use target="_blank" as any validation errors show up in the new


window.

Did you find a solution to your problem?

Re: Programattically invoke Action's execute()


Author: Latha Rao (http://www.jguru.com/guru/viewbio.jsp?EID=1157483),
Sep 27, 2004
I have a similar requirement where I need to display results in a new window.

I cannot use target="_blank" as any validation errors show up in the new


window.

Did you find a solution to your problem?


Re: Programattically invoke Action's execute()
Author: Latha Rao (http://www.jguru.com/guru/viewbio.jsp?EID=1157483),
Sep 27, 2004
I have a similar requirement where I need to display results in a new window.

I cannot use target="_blank" as any validation errors show up in the new


window.

Did you find a solution to your problem?

I am new to Struts and Hibernate. I need sample project to execute to how to


use struts and hibernate with oracle.
Author: senthilkumar ramamoorthy
(http://www.jguru.com/guru/viewbio.jsp?EID=1170955), May 15, 2004
Hi All, I am interested in learning struts and hibernate. I have choosen my back
end as oracle. I have some basic knowledge on struts. I would like to use struts
and hibernate with oracle for a small project. If anybody has the sample source
code which you have already implemented the same can you please share your
experience. Expecting your favourable reply.

IMG tag Hello,

I use the tag IMG to display images on my site - It however looks like I am
limited in what I attempt to do because this tag can only access images that
are located within the application directory.

The problem is that I have an image repository elswhere on my disk drive


and that I cannot move it within the application directory.

QUESTION: How do I get IMG tag to work with images outside of the
application diretory??? any workaround?

Thanks
Location: http://www.jguru.com/faq/view.jsp?EID=1039820
Created: Dec 19, 2002
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by julien dolon
(http://www.jguru.com/guru/viewbio.jsp?EID=1033690

The Struts JSP tags solve the problems of

• accessing application resources without embedding the application context in


your URI, and
• accessing application resources that might require an authenticated user
In the former case, the tags insert the application context for you. (Along with the
module context in Struts 1.1.) In the later case, the tags encode the URI so that the
user's session is maintained.

If neither of these use cases apply, then don't use the Struts tags. =:0)

So the answer to your question is to use a plain old <img> tag. The Struts tags are
not a value-add here; don't use them.

Sometimes, people do seem to get the idea that every tag on a page should be a
Struts tag. But that is not how the tags are designed to be used, and no one on the
Struts team would recommend such a practice.

-- Ted Husted, Struts in Action.

Comments and alternative answers

What about the src attribute?


Author: Erik Hatcher (http://www.jguru.com/guru/viewbio.jsp?EID=405274), Dec 21,
2002
I believe if you use the src attribute on <html:img> that you can point to images
outside of your application also.

Re: What about the src attribute?


Author: Shawn Brinkman
(http://www.jguru.com/guru/viewbio.jsp?EID=1104074), Jul 25, 2003
I 'm having the same problem but I'm using an image for a submit button in a
form. Is there an easy way to fix this. Thank you Shawn

Problem to display image in jsp


Author: Koteswar Patnaik
(http://www.jguru.com/guru/viewbio.jsp?EID=1187106), Aug 30, 2004
Hi
I am getting bytes from database to display image.
I can simplay display image out.write(bytes); where out is an OutputStream
object. But I am not able to display any other contents like buttons are any
other text. Plese tell me if you know some thing how to display image as well
as other content in jsps.
Thanks
koti

img tag
Author: Sarit Seal (http://www.jguru.com/guru/viewbio.jsp?EID=443942), May 26,
2005
In the src attribute of the img tag use an url which points to a servlet. The servlet can
write the bytes directly to the response buffer. You need to take care of the content-
type entries in the HTTP header field. The bytes can be read by helper classes from
the database or file system. img src="http://<server>/servlet"

A "switch case" tag - Maybe Tedd knows??? Hi,

Is there some sort of "switch case" tag existing?

My point is that I want to avoid to use plenty of:

<logic:equal name="theBean" parameter="theParameter" value="0">


</logic:equal>
<logic:notEqual name="theBean" parameter="theParameter" value="0">
<logic:equal name="theBean" parameter="theParameter" value="5">
</logic:equal>
<logic:notEqual name="theBean" parameter="theParameter" value="5">
<logic:equal name="theBean" parameter="theParameter" value="8">
</logic:equal>
<logic:notEqual name="theBean" parameter="theParameter" value="8">
</logic:equal>
</logic:equal>
</logic:equal>

To use something that would look like this:

<imaginaryLogic:switch name="theBean"
parameter="theParameter">
<imaginaryLogic:switchCase value="0">
aaa
</imaginaryLogic:switchCase>
<imaginaryLogic:switchCase value="5">
bbb
</imaginaryLogic:switchCase>
<imaginaryLogic:switchCase value="8">
ccc
</imaginaryLogic:switchCase>
</imaginaryLogic:switch>

Thanks!
Location: http://www.jguru.com/faq/view.jsp?EID=1045710
Created: Jan 13, 2003
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by Jerome Iffrig
(http://www.jguru.com/guru/viewbio.jsp?EID=977875

The Struts taglibs are not designed for this sort of thing. The idea is that in a Model 2
MVC application, you would put the equivalent of the switch into the ActionForm itself
so you don't have to go to such lengths. You would also not generally use a HTTP
parameter, but a property from the ActionForm. (The bean properties like
"parameter" are handy for transitioning from Model 1 to Model 2, but personally I
would get away from them ASAP.)
So, there should be a ActionForm property that would be populated (automatically)
by the controller. A helper property could then look at the property and output
whatever it is you need here.

In a Model 2/MVC application, the pages should be glofified mail-merge jobs. If you
feel the need for a swtich statement or anything like that, you are drifting back
toward a Model 1 application.

Of course, you *can* write Model 1 applications with Struts, but it's not something
I've ever done myself =:0)

As mentioned, the new JSTL taglib does have many features appropriate for Model 1
applications. If you are making use of the JSTL, see also the new EL taglib in Struts
beta 3 and the nightly build.

HTH, Ted.

Comments and alternative answers

present/notPresent, empty/notEmpty distinctions OK, in Model 2 presentation


logic, unlike "equal"?
Author: Christopher Koenigsberg
(http://www.jguru.com/guru/viewbio.jsp?EID=722897), Jan 13, 2003

You remind me of the following question I have.

I tend to use a lot of paired "logic:present" and "logic:notPresent" tags (also


"logic:empty" and "logic:notEmpty") in my Struts JSP form pages so far, to handle
the special/boundary cases/situations, where no results were returned, or where none
have been requested yet, etc. Otherwise the Struts tags will throw exceptions when
collections are empty etc.

Maybe I should reconsider my designs? or would you say the "present/notPresent",


and "empty/notEmpty", are OK, in designing presentation logic?

For instance, maybe I am displaying a list of items to select, based on a search from
business logic, in columns and rows inside a table, pulled in through a "logic:iterate"
or "optionsCollection". The first time the page comes up, there was no search yet, so
there are no results yet, and I don't want to display headers for an empty list in an
empty table. But subsequently there will be the "current" search results in the list,
with headers ("pick one from these results" etc.) plus form fields to conduct a new
search again, etc.

To do this all in the same JSP page and the same form (both the initial search, and
subsequent "pick from current list" along with "new search"), it seems that I need the
present/notPresent, empty/notEmpty, also to tell if the size of a collection is greater
than 0 or not, in the presentation logic of the page tags themselves.

Isn't this a good reason to use switch/cases in the presentation layer?


Author: Jerome Iffrig (http://www.jguru.com/guru/viewbio.jsp?EID=977875), Jan 24,
2003
Well, I normally don't make use of switches / cases in my presentation layer (JSP
page) but in this particular case I did not see how to do otherwise:

I am displaying my users’ info within a table,


Depending on the nature of a column, the elements of this column would be rendered
differently.

An example:
Lets say that one of my columns contains the links to my users' perso webpage - The
header of my table would know about the nature of a given column (each entry of the
table's header is actually a bean containing some extra information about the content
held by its associated column) - while displaying the table (by iteration), I need to
check if the table entry I am about to render is a user webpage link, and if it is the
case, I need to render it accordingly for it to be “clickable” by a visitor.
Likewise for a column containing the users' e-mail addresses: while rendering the
table, I dynamically check the nature of the columns and render it differently
depending on its nature.

Furthermore, the visitor is free to display the table differently if he/she wishes (e.g. it
is possible to move any column left or right, add or remove columns .etc…) so the
rendering of the columns MUST be in live.

Conclusion: displaying my users table, each time I iterate and display a row, I
dynamically check the nature of a given cellule (belonging to a specific column) –
Depending on this nature (e.g. Constent.WWW_LINK, or Constent.EMAIL .etc…) I
render it differently (web link or mailto .etc…) and this can only be done via a switch
/ cases within the iterate tag as far as I can see.

Let me know your point of view.

Jérôme.

Re: Isn't this a good reason to use switch/cases in the presentation layer?
Author: Jennifer Grucza (http://www.jguru.com/guru/viewbio.jsp?EID=1064289),
Mar 7, 2003
Hey Jerome, if I were you, I would write my own custom tag to handle this logic
and display. Then your JSP becomes very simple.
switches are valid for model 2 presentation layer
Author: Wiebe de Jong (http://www.jguru.com/guru/viewbio.jsp?EID=2065), Aug 9,
2004
I recently had a problem to solve which required a switch functionality: a page was
displaying a list of accounts, 1 per line, and at the end of the line I needed to display
an assortment of links based on the status of the account. I originally did the nested
logic:equal as Jerome did, because I needed to test for the condition where a new
account status had been added to the database and not the jsp. It was ugly and I went
looking for a better way. I found a taglib example that implements switch and case
(http://www.orionserver.com/tutorials/taglibs/4.html), and added my own default tag.

I'm trying to use the ActionError facility in Struts 1.1-b3. I create and save
my error in my action. But when I try to render my error page, using this
tag <html:errors/> I get this error message;
javax.servlet.ServletException: Cannot find message resources under key
org.apache.struts.action.MESSAGE and the root cause is the same
I have an ApplicationResources.properties file in my WEB-
INF\classes\resources with this line;
error.register.passwordretry=Oooops, error
The same key I used to save the error in my action class.

Location: http://www.jguru.com/faq/view.jsp?EID=1055463
Created: Feb 10, 2003
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by Jan Gifvars
(http://www.jguru.com/guru/viewbio.jsp?EID=1051641

Under Struts 1.1 b3 and later, you need to specify the messages resources in the
struts-config:

<message-resources parameter="resources.ApplicationResources">

This can go at the very end of the struts-config, after the action-mappings, and any
of the other new elements you may be using.

HTH, Ted.

Comments and alternative answers

a possible solution
Author: Roger Zacharias (http://www.jguru.com/guru/viewbio.jsp?EID=1171837),
May 19, 2004
Hi, We solved the problem by: 1. if there isn´t one in the web.xml put a "/" in front of
your "WEB-INF/..." 2. set load-on-startup to "1" Environment: Tomcat 5.0.24
Regards, Roger

Struts logic:iterate/ anf bean:write/


Author: sujoy acharya (http://www.jguru.com/guru/viewbio.jsp?EID=1189073), Jul
28, 2004
Hi all, as u all know that if u have one collection of value objects and u want to
populate some select box then u just write <html:options collection="Name"
property="getterMethods" labelProperty="..."/> but if u have member like eMail what
will u give in property field ? simply 'eMail' coz getter method name is getEMail() but
it doesn't work in <bean:write /> here u ve 2 write <bean:write property="EMail" />
also frenz don't forget to put "<message-resources parameter="resources.Applicat..."
in strut-config.xml ;) sujoy

ActionErrors
Author: Sudha Rani (http://www.jguru.com/guru/viewbio.jsp?EID=1222332), Jan 20,
2005
Even after specifying the message resources using the <message-resources> tag I'm
still getting the above specified error.

Re: ActionErrors
Author: Vikas Sharda (http://www.jguru.com/guru/viewbio.jsp?EID=1224589),
Feb 1, 2005
The best and tested way to resolve this error is to tell Struts where your resource
bundle is. It's one of the servlet initialization parameters in web.xml. <servlet>
<servlet-name>credux</servlet-name> <servlet-
class>org.apache.struts.action.ActionServlet</servlet-class> <init-param>
<param-name>application</param-name> <param-
value>path.to.your.resourcebundle</param-value> </init-param> </servlet> Try
this out it helped me to resolve the problem. Thank you Vikas

I have a button on my form that's suppose to submit the form. The script
works on other forms, but not when I use it with Struts. Why would this be?

Location: http://www.jguru.com/faq/view.jsp?EID=1057599
Created: Feb 17, 2003
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by Agustín Ané
(http://www.jguru.com/guru/viewbio.jsp?EID=1056228

By default, the <html:submit> button is also named (surprise) Submit. To avoid


conflicts, give the Submit button another name.

<html:submit property="submitButton:/>

HTH, Ted.

---
Struts in Action

Comments and alternative answers


Re: Submit form
Author: Andreas Aune (http://www.jguru.com/guru/viewbio.jsp?EID=1178385), Jun
13, 2004
Hi! I have had the same problem, and eventually I came up with this solution (my
submit-button has the name attribute set to 'sendForm'):
function send() {
document.movCabForm.sendForm.click()
}

This sends the form. I spent hours trying to use the submit()-method, but that never
worked out for me.

Andreas

Re[2]: Submit form


Author: Esteve Olm (http://www.jguru.com/guru/viewbio.jsp?EID=1171236), Jul
12, 2005

The submit()-method must be executed from the form element, not on the submit
button:

document.movCabForm.sumbit()

Is there a way to lock a form if the form is in use? The intention is to avoid
two users submitting the same form.
Location: http://www.jguru.com/faq/view.jsp?EID=1057607
Created: Feb 17, 2003
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

Your options here are the same as with any enterprise application.

• Pessimistic locking, and


• Optimistic locking

For a pessimistic lock, you need some flag on the record that says someone has
checked it out, along with some record of who. When an administrator starts the
order workflow, you update the database. If someone else try to start the same
order, you branch to a page that tells them they can't do that.

This pretty much works, but you also need a good routine for unlocking the order,
since some people will invariably fail to complete the workflow and leave a record
locked.

For an optimistic lock, you need a version flag on the record. When someone
retrieves the record, you include the version number. Before saving the record, you
check the version in the database. If it doesn't match, then someone else has beaten
your user to the punch, and you branch to a page explaining the problem.

Optimistic locks are fine when the chance of contention is low and the changes are
usually minimal. Pessimistic locks are better when the chance of contention is high
and the changes are either non-minimal or critical.

Scott Ambler's papers provide some good background about this

• http://www.ambysoft.com/persistenceLayer.pdf
• http://www.ambysoft.com/mappingObjects.pdf

I have a telemarketing application that uses pessimistic locks to keep people from
trying to call the same person at once. Though, for most things, optimistic locks work
well.

HTH, Ted.
---
Struts in Action

For keeping someone from submitting the same form twice, Struts has a built-in
token feature, but that's a different question =:0)

Comments and alternative answers

Telemarketing App
Author: Brad Peterson (http://www.jguru.com/guru/viewbio.jsp?EID=1073318), Apr
4, 2003
Did you put code into the telemarketing app protecting your phone number? Can you
do it for mine? :)

Do all the ActionMappings share one action instance? What happens when I
have a custom Action that uses property setters from the struts-config.xml
to set properties during use of that action.
Location: http://www.jguru.com/faq/view.jsp?EID=1057609
Created: Feb 17, 2003
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

Yes, all the ActionMappings share one Action instance. But, you wouldn't be setting
the properties of the Action object here but the *ActionMapping* bean. To get to
your custom properties, you would refer to the mapping instance that is passed to
execute/perform. So, each mapping would have their own set.

The ActionMapping bean is a decorator that the Action object can use to affect its
runtime behavior, but the Action objects are singletons. Which ActionMapping first
triggers the instantiation of the Action doesn't matter.
HTH, Ted.
---
Struts in Action

We're using EJBs as for our Model. Is it correct for the Action to know about
the Model interfaces?
Location: http://www.jguru.com/faq/view.jsp?EID=1057611
Created: Feb 17, 2003
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

If you are using EJBs for the business logic layer, then yes, it's perfectly all right to
bind your Actions to the EJB interfaces.

Though, some people do prefer to use EJBs as a persistence layer and then put a
Facade between something like a Struts Action and the actual EJB interfaces.

It's mainly how sold you are on the EJBs. If you use a Facade it would be easier to
use something else later, since you would just rewrite the Facade rather than all the
Actions.

Some people also find that a Facade actually simplifies much of the Action/EJB
programming, and it can pay for itself even if you never use anything else.

In general, it is in fact the Actions job to know about the Model interfaces, and well
as which View to call depending on how the calls to the Model turn out.

In practice, there are usually distinct Business Logic layer and Data Persistance layer
with the Model. Ideally, the Action should just call the Business Logic portion of the
Model, so that it is not coupled to the Data Persistance portion. Data Persistance is
one of those implementation details that people like to change over time.

In this case, a Facade (or Session Facade) could handle the Business Logic and might
be able to hide other EJB details from the Action.

HTH, Ted.
---
Struts in Action

Comments and alternative answers

use delegate pattern


Author: sriram sundararajan (http://www.jguru.com/guru/viewbio.jsp?EID=807908),
Nov 9, 2004
Hi,

It is not advicable to use the session facade directly from the presentation tier,
eventhough if we are calling it in the Action class still it is in the presentation layer.
Use delegate pattern in the presentation layer and use your facade inside your
delegate.

I would like to isolate the business logic to a bean class and use the scaffold
ProcessAction class ala the Artimus app in Struts in Action. Since the bean
class has all the business logic, how do I communicate errors?
Location: http://www.jguru.com/faq/view.jsp?EID=1057612
Created: Feb 17, 2003
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

Excellent question! The Scaffold solution is to use a ProcessResult object that


encapsulates the typical things that the Model might want to send back to the
Controller/View. So far, it can transfer data, a numeric code, messages, a dispatch
instruction, along with a name and a scope.

If the ProcessAction sees that the ProcessResult contains messages, it converts those
to ActionMessages. If it sees it contains data, it expose that data under the given
name and scope. And so forth.

ProcessAction uses a very simple message format. It's just a list where the first entry
is the template key and everything else is replacement parameters. Easy to build,
but you can only send back one message.

Now that we have a Message object in the Commons, I'm migrating a new version of
ProcessResult/ProcessAction to use the Commons Messaging. But, the basic design
pattern remains the same.

HTH, Ted.
---
Struts in Action

Comments and alternative answers

API docs?
Author: Kirby Vandivort (http://www.jguru.com/guru/viewbio.jsp?EID=207090), Mar
20, 2003
Where can I find the docs for the scaffold API? I've downloaded the zip file, but it
doesn't seem to be quite complete. The scaffold jar file has classes in it in the
org.apache....scaffold.util, but the docs that come in the zip file don't have docs for
those classes, such as ProcessBeanBase.

As an example of what I'm needing, I'm looking at artimus, and classes like
MenuCreate are calling methods like saveResult with three params and I can't find
much of a description of what that means or what is available. I'm considering using
this idea for a project that I'm working on, but documentation is sparse. The jarkarta
site has nothing on scaffold other than webcvs.
The problem I am noticing is that when the second action is being invoked,
the form is being 'repopulated' with the initial form values that the form had
when it was passed to the first action.
Location: http://www.jguru.com/faq/view.jsp?EID=1057613
Created: Feb 17, 2003
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

This is an excellent example of what we mean when we talk about "Action chaining",
or, as I like to call it, the "dark side of Struts".

There is a very fine design pattern called "Chain of Responsibility" which "Design
Patterns"[*] define as "Avoid coupling the sender of a request to its receiver by
giving more than one object a chance to handle the request. Chain the receiving
objects and pass the request along the chain until an object handles it."

Struts does *not* implement a CoR at the Action level. The design is that the Action
is the request handler and should do whatever is necessary to complete the
transaction, use-case, or story underlying the request.

Since it does not implement a CoR, it does try to populate the ActionForm with every
request.

IMHO, the place to implement a Chain of Responsibility is within your Model. If you
need anything this complex, you are a candidate for what "Patterns of Enterprise
Application Architecture" [*] calls "Domain Objects". You can convert the HTTP
request to a business request (of your own devise) and pass it to as many handlers
as you see fit.

Personally, I believe implementing a CoR using Struts Actions is a step in the wrong
direction. IMHO, we are trying to pull ourselves away from the web tier, not dive
back into it =:0)

There are times when one Action should forward to another, but only to display the
final result. Using a second action to complete a business transaction is where we
start sliding toward the dark side.

But, each to their own.

First, avoid trying to set parameters in the request. Better to set properties on the
ActionForm (or other object in the request) that you can control. If the properties are
not exposed in the request as parameters, then Struts will ignore them like visitors
on a Borg ship.

If you need to tweak ActionForm properties so that they do no match the


parameters, in Struts 1.0.x, you can defeat autopopulate by setting up your own
"mutable" or "locked" sentry. In each of your setters, put a test like

if (mutable) { ... do the setting }


So if you setMutable(false), then no one can overwrite your maverick data. (Ahh, the
magic of JavaBeans!) If one of your actions needs to do some more tweaking, they
an unlock the bean and then lock it again.

In Struts 1.1, you could also do clever things with the processPopulate of the
RequestHandler.

HTH, Ted.

[*] See the Struts "Other Books" page for links to these and other fine references

HTH, Ted.
---
Struts in Action

Comments and alternative answers

Struts:Action
Author: Sunil phanse (http://www.jguru.com/guru/viewbio.jsp?EID=65326), Jul 22,
2003
If i want to do following : 1. Certain processing at Action1 2. Update the Form-bean
in this Action1 3. And send that formbean to Action2, Then what should i do? I know
i have to avoid this things but still i need to handle this type of case. Is there any
solution in ActionServlet class or ActionMapping class?

Re: Struts:Action
Author: Tinku Abraham (http://www.jguru.com/guru/viewbio.jsp?EID=1223937),
Jan 29, 2005
I think i got a simple and clean method for this problem In the action Mapping i
added a parameter "reset" as
---------------------------------------------
<forward
path="/pg/employee/EmployeeDetailSearch?reqCode=search&reset=true"
name="returnback" />
---------------------------------------------
Then in the reset of the target form bean i checked
---------------------------------------------
if(arg1.getParameter("reset")!=null) setMutable(true); else setMutable(false);
---------------------------------------------
Then in each setters i checked as
---------------------------------------------
if(isMutable()==false) empNo = string;
---------------------------------------------
Now every thing is fine

action chaining in Struts


Author: santosh gokak (http://www.jguru.com/guru/viewbio.jsp?EID=1244209), May
16, 2005
This problem can be over come by using the reset() method of your respective
actionform related to each action used in the chain.
Just call the rest method on entering the action
and do your processing and then forward to the jsp.
The JSP will show the new values (not the old) which u assigned it or
if not,the values u assigned it in reset() method (where we generally assign everything
with blanks and zeros.)

if any alternatives or problems, u can mail me at:s_gokak@rediffmail.com

Forward ActionForm To Another


Author: Forum ans (http://www.jguru.com/guru/viewbio.jsp?EID=442866), Jun
28, 2005
Hi,

I am inside Action_A. Now I have to goto Action_B.

Action_B retrieves values from ActionForm_B. So before moving to Action_B


from Action_A, I have to populate ActionForm_B and then forward it to
Action_B.

After populating ActionForm_B, where to put it? In session or request? Under


what name I have to put it so that Action_B can see it?

As default, I18N Struts-applications are managed by the language in the


browser. I would like it to be based on a language-code in the users login
and thus I need to set the locale/language designation that controls Struts.
.
Location: http://www.jguru.com/faq/view.jsp?EID=1057614
Created: Feb 17, 2003
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

As far as I know, by default, Struts applications are governed by the default locale of
the container/JVM hosting the application. (The last thing Struts is going to do is
trust what some whacky browser has to say about it! [:0])

The controller creates a default locale object and places it in the session. The other
components look for the object under that key to decide what locale to use. To
change the locale, change the locale object in the session.

It can be convenient to put methods to access the locale object on a base Action or
base ActionForm:

Action:
protected Locale getLocale(HttpServletRequest request) {

Locale result = null;


HttpSession session = request.getSession();
if (session!=null) {
result = (Locale) session.getAttribute(Action.LOCALE_KEY);
if (result == null) result = Locale.getDefault();
} else {
result = Locale.getDefault();
}

return result;

} // end getLocale()

protected void setLocale(


HttpServletRequest request,
Locale locale) {

HttpSession session = request.getSession(true);


session.setAttribute(Action.LOCALE_KEY,locale);

} // end setLocale()

ActionForm:

public static String STRUTS_LOCALE_KEY = Action.LOCALE_KEY;

private Locale locale = null;

public void setSessionLocale(Locale locale) {


this.locale = locale;
}

public Locale getSessionLocale() {


return this.locale;
}

public String getSessionLocaleName() {


return STRUTS_LOCALE_KEY;
}

protected void resetSessionLocale(HttpServletRequest request) {

HttpSession session = request.getSession();


if (session!=null) {

setSessionLocale((Locale)
session.getAttribute(getSessionLocaleName()));

}
else {

setSessionLocale(Locale.getDefault());
}
} // end resetSessionLocale

protected void putSessionLocale(HttpServletRequest request) {

Locale locale = getSessionLocale();


if (null==locale) locale = Locale.getDefault();

request.getSession(true).setAttribute(Action.LOCALE_KEY,locale);

} // end putSessionLocale

public String getLocaleDisplay() {

Locale locale = getSessionLocale();


if (null==locale) locale = Locale.getDefault();
return locale.getDisplayName();

} // end getLocaleDisplay

public void setLocaleDisplay(String language) {


setSessionLocale(new Locale(language,EMPTY));
}

These and other convenience methods are part of the BaseAction and BaseForm in
the Scaffold package of the Struts contrib folder.

HTH, Ted.
---
Struts in Action

Comments and alternative answers

The locale is taken from the browser!


Author: Flo Rickert (http://www.jguru.com/guru/viewbio.jsp?EID=1065810), Mar 13,
2003
Hi! I just wanted to let you know that the locale is taken from the browser. And it's
better this way. Thus a person from Spain (with a Spanish locale set in the browser)
will see the page in Spanish and a person from France in French. Flo

Re: The locale is taken from the browser!


Author: juan jara (http://www.jguru.com/guru/viewbio.jsp?EID=918468), Jan 23,
2004
Hello Flo: Iam new in all this. How do you get the Locale from the browser/Any
examples??? Thx Juan Jara

Re[2]: The locale is taken from the browser!


Author: raja bhanu ari
(http://www.jguru.com/guru/viewbio.jsp?EID=1145732), Feb 12, 2004
open the explorer and go to tools/internet options.. there select the
languages.....

Re[2]: The locale is taken from the browser!


Author: david sissoko
(http://www.jguru.com/guru/viewbio.jsp?EID=1155554), Mar 18, 2004
see method getLocale() of HttpServletRequest class

Re[2]: The locale is taken from the browser!


Author: abhishek shrivastava
(http://www.jguru.com/guru/viewbio.jsp?EID=1219583), Jan 25, 2005
hi... If u r using struts just write <html:html locale="true"> im place of
<html:html> in ur jsp page... use the application_resources_en.properties file
as default if u want English as the default language... if want to display ur
pages in japanese then just add one more application_resources_ja.properties
file in ur resources.... and use the native2ascii tool to convert ur english text
into UTF-8 encoding.this tool is in ur j2sdk1.4.2_05/bin and the command line
is java/bin:> native2ascii -encoding UTF-8 inputfile.properties
outputfile.properties in the output.properties file u will get texts as
\uab34\uaaa.... add this properties file as ur japanese application resources
Remember u will have to convert the english texts into the japanese/spanish....
texts using any language translator... only then u can convert ur english
properties file in the UTF-8 encoding... now its over... select the language
option of different browsers.... whatever language u will select u will see ur
pages in that language.... it so easy.... Good luck... Abhishek

I need to populate property lists in an ActionForm from a database. For


different application user, I store the userid in session attribute. The data is
based on userid. How can I get the userid session attribute within the
ActionForm? I know it's easy to do this in an Action class, but I would like to
do it in the JSP.
Location: http://www.jguru.com/faq/view.jsp?EID=1057616
Created: Feb 17, 2003
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by Bao Qu (http://www.jguru.com/guru/viewbio.jsp?EID=1055838

The HttpServletRequest is passed to the reset method, which gives you access to the
session. It's preferred to do such things in an Action, but you can access database in
the reset (or validate) methods as well.

How to display a confirmation dialog

I am using an <html:image> tag for logout submit action. Before logout,


using the onclick event, I am displaying a confirmation dialog box. I wish to
disable the submit action if the user clicks on 'No' in the confirmation box.
How do I code this? The code I am using is : <html:image src="logout.gif"
value="logout" onclick="confirmLogout()"/> The confirmLogout() method
just displays a warning to the user if he wishes to logout.
Location: http://www.jguru.com/faq/view.jsp?EID=1066823
Created: Mar 17, 2003
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by Bhavin Shah
(http://www.jguru.com/guru/viewbio.jsp?EID=101978

Generally, the simplest thing is to just have the JavaScript window popup. If they
click no, just close the window. If they click yes, then submit the request. If they
cannot submit the logout request without clicking yes, then you don't need to disable
anything.

I would not recommend disabling the button if they click no, since they might change
their mind.

In my own applications, I just do something like this:

<SCRIPT language="JavaScript">
<!--
function create() {
var go = confirm("Are you sure?");
if (go == true) {
bCancel=false;
set("create");
return true;
}
else {
return false;
}
}
//-->
</SCRIPT>

Where "bCancel" is the JavaScript variable used by the Validator tag.

HTH, Ted.
---
Struts in Action

Comments and alternative answers

Disable validations for a method


Author: Shan Thiruvarur (http://www.jguru.com/guru/viewbio.jsp?EID=1002368),
Mar 11, 2004
Hi Ted ... Thats right but what if if i wish to disable validations for a method
accessing the action form in my action class ? ( FYI I'm using DynaValidatorForm
and LookupDispatchAction. )

Dynamic pages using struts


Is it possible to create the elements of a page(jsp) dynamically based on
the results of a data base query, when using struts framework?
Location: http://www.jguru.com/faq/view.jsp?EID=1067793
Created: Mar 19, 2003
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by Madhan Prabahar
(http://www.jguru.com/guru/viewbio.jsp?EID=1060778

If you are talking about rendering a report, then sure. The Action iteracts with the
business layer/data access objects to acquire the data, and then passes it to the
presentation page bundled up as a JavaBean or a collection of JavaBeans. The JSP
tags (and other systems) all use reflection, so you can use whatever JavaBean you
like.

If you are talking about creating a dynamic data-entry form, then "not so much".

Struts 1.1 supports map-backed ActionForms, but the page still needs to know what
input fields are going to be needed. For a truly dynamic input form, I guess the key
would be some type of tag that took a map and then generated a column of input
fields. (Wouldn't work for everyone, since a lot of forms must be designed just so.)
For extra credit, the entry names could (optionally) be resource keys that were used
to find the label text.

Text fields would be easy. Others would need some type of JavaBean with properties
to tell the tag what to output. A bit of work, but obviously doable.

Of course, you'd probably want to validate the form before passing it back to the
database. I imagine it's possible to use the validator in a non-declarative way, but I
don't know anyone whose doing that. If you can do a db query to get the information
about the form, I imagine you could also do a query to get the information about
validations for the form. It would probably be easier to write your own engine than
adopt the validator. (It's not really that complicated to do.)

People often ask about "dynamic input forms", but most of us just can't get our head
around the use case. It's hard to understand what you do with the dynamic data
when it comes back. Most application don't allow you to input or update an arbitrary
(e.g. dynamic) set of fields.

HTH, Ted.
---
Struts in Action

Comments and alternative answers

Re: Dynamic Pages using Struts


Author: Jennifer Montello (http://www.jguru.com/guru/viewbio.jsp?EID=1017254),
Mar 21, 2003
Ted,
I would use this capability to create input pages that are driven by config files. This is
only for an input page where we expect the information we need to collect to change
frequently, and where the server side uses a similar scheme do decide how to store the
data we collect.

Dynamic Input Forms and Struts


Author: will chen (http://www.jguru.com/guru/viewbio.jsp?EID=1082390), May 6,
2003

I have to disagree that there are not many cases where a dynamic form in struts could
come in handy. If we have an user administrating a list of objects then we have this
case. Examples: an inventory of products with pricing and/or availability,
administration of songs and their playlist properties that play on a music server, an
admin modifing User's read/write profiles, etc. It would be a nice to have Struts deal
with this issue.

my $.02 :)

Re: Dynamic Input Forms and Struts


Author: Srinivasa Rallabandi
(http://www.jguru.com/guru/viewbio.jsp?EID=1086206), May 19, 2003
I encountered the same problem where I have to create table driven HTML input
fields in the form. I have say hundred forms but they share most common input
fields around 20. I keep the fields in the database and generate HTML as I want.
Till now I tried ( radio, text, select, textarea ). In my form lets say, XyzForm, I
declare a member HashMap and save all the input. Since the form is available in
the JSP page, I see if it is not null, retrieve the data and prepopulate it. It works for
me.

Re[2]: Dynamic Input Forms and Struts


Author: Bollempalli rani
(http://www.jguru.com/guru/viewbio.jsp?EID=469037), Mar 8, 2004
Hi, Could you please tell me how you done this. Thanks in Advance
Bollempalli

Dynamic Form Use case


Author: Michael Motal (http://www.jguru.com/guru/viewbio.jsp?EID=399205), May
20, 2003
I'm working on a application to front our payroll system to allow employees the
ability to enter their times directly. Each employee can allocate their time to 1 to n
departments. They can allocate their overtime (if applicable) to 1 to n departments.
They can use 0 to n types of special pay (Leave, bereavement, jury duty, etc.).
The basic timesheet definition is read from a database. The user enters start and end
times and assigns the hours to various departments. They may add a new department.
They may delete a department. The back end handling of the data is very simple and
just involves a stored procedure which takes in the userid, time period, department,
and times and hours.
As part of the form validation, I'd like to take the time in/time out for Tuesday, for
example, calculate how many hours were worked, add up all the allocated hours
entered by the user (across 1 to n departments) and return an error if the allocated
hours exceed the calculated time in/time out hours. The problem is that I don't know
the fields in advance for the validation.

Re: Dynamic Form Use case


Author: Brad Schneider (http://www.jguru.com/guru/viewbio.jsp?EID=1089492), May 30,
2003
I found this explanation on the Struts Official Website.
http://jakarta.apache.org/struts/userGuide/building_controller.html#map_action_form_classes

Dynamically Generated Forms


Author: Josh Hagan (http://www.jguru.com/guru/viewbio.jsp?EID=1093964), Feb 23,
2004
I am surprised, Ted, that the struts team has been unable to get your heads around a
use case for dynamically generated forms. My team and I have spent the last two
years building three different applications in three different technologies, which all
dynamically generate forms. It is worth noting that these projects were all separate in
their requirments, but it seemed in each case that to allow the user to create their own
forms was necessary. The last and current one we are working on is in fact using
Struts w/ Velocity. Nonetheless, map-backed ActionForms appear to do the job
sufficiently.

dynamic forms...
Author: John Mark (http://www.jguru.com/guru/viewbio.jsp?EID=1168057), May 4,
2004
I have a need for dynamic forms - we have a survey / form system that allows users to
build surveys, specify validation, etc... obviously each user will have their own sets of
questions and answers. We allready have it workign (not in struts) but I would like to
have it use the validator framework and some sort of actionform... that would be nice
to play with.

Need Dynamic Input form


Author: BJ T (http://www.jguru.com/guru/viewbio.jsp?EID=1169942), May 11, 2004
We too are in need to dynamic input form using struts. The use case scenario is :
Based on configuration file, user should be presented various query attributes,
conditions and then get values before actually executing the query. As there will be
many reports, each report will have its own set of attributes which should be
presented to user for getting the execution criteria. Thanks BJ

Re: Need Dynamic Input form


Author: Victor Nebot (http://www.jguru.com/guru/viewbio.jsp?EID=1183117), Jul 1, 2004
As Brad said:
http://jakarta.apache.org/struts/userGuide/building_controller.html#map_action_form_classes
I Just finished a tiny test and it works great!!!
Re: Need Dynamic Input form
Author: nitin karande (http://www.jguru.com/guru/viewbio.jsp?EID=1203532),
Oct 5, 2004
i have also same requirement.. can u plz..provide solution...

Re[2]: Need Dynamic Input form


Author: ArunSakthi KalyanaSundaram
(http://www.jguru.com/guru/viewbio.jsp?EID=1244624), May 18, 2005
We are planning to create a JSP with the fields getting populated dynamically.
Say iam gong to have some fields like Name, Address etc.., the field names
has to be obtained from a database or something. Can any one please help if
you have done anythinh similar to this before.

I'm in the process of converting a webapp to using struts, am trying to use


"best" practices to make sure that I keep presentation split from business,
and I was wondering what all of you experts do to handle the data
transition from model business logic beans to the presentation.

As I see it, I can make what amounts to a bean for every single page that is
going to be presenting data to the user. The bean contains the data and the
JSP then displays the values in the bean.

That seems like a real pain to have XXX beans. It's just a pain to have to
make hundreds of bean classes. I suspect that I'm missing something here,
but this is what i'm seeing.

Most of the struts documentation that i can find doesn't really address the
simple case of wanting to print data to the user. Lots of discussion of
making forms in struts, but I'm just wanting to send data back to the
presentation...

The struts-example seems to basically use a single user bean that contains
all the data and doesn't ever really do much business prep of return data;
Artimus uses scaffolding to wrap everything in; struts-polls seems to use
Collection and jsp knowledge of class names to get the data out..

So, I guess my question is... is there a consensus of any sort on how this
should be done or, how do you do it, etc?

Thanks, Kirby V.
Location: http://www.jguru.com/faq/view.jsp?EID=1069987
Created: Mar 26, 2003
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

If you are just presenting data to the user, then I would say just go ahead and use
the model beans. The one thing to watch for is whether there are any properties that
call back to the model. If there are, you need to make sure that everyone writing a
presentation page that uses this bean knows which properties to call (and which NOT
to call).
But as long as you are presenting properties that have already been transferred from
the data storage to working memory, just do it. =:0)

The presentation page uses reflection, so you are not coupling your page to the
model bean type but to its "protocol" -- what it names the properties. If the model
bean properties ever change, you can always substitute an adapter, or "wrapper"
bean, that maps the new properties to the old properties. (Or just update the pages,
whichever is preferable.)

Gathering input from the user is a thornier problem.

(1) The first issue is that ActionForms should only use String and boolean properties.
Why? Because the primary job of an ActionForm is to allow for validating input. A
non-String property can't store whatever invalid input a client might present. We
could just throw it away, but the classic Struts use case has always been that we
should present invalid input for correction, exactly as it was input.

There is nothing to prevent you from using an Integer for an ActionForm property,
but if the user inputs "12ZY4" you can't re-present that value for correction.

<ot> Though, I've been wondering why we just don't have the tags (or whatever)
check the request if a property is null, and use the request for the input buffer
instead. (I might try this in Velocity.) There has also been a recent patch proposed
regarding validating maps, which might also work for a HttpRequest. If we can use
the request to buffer invalid data, then we can use native types. If we can use native
types, then it becomes easier to implement a business interface on your ActionForm.
Business methods can then interact through the interface. </ot>

One alternative here is to provide both Strings and native versions of your properties
(like a ResultSet). But then you either end up replicating the String properties or
creating confusion over which property to call when. If you go this way, pretty soon it
becomes just as easy to maintain two separate beans with distinct purposes.

(2) The second argument is security. Populating a method on a business bean might
fire a business process that we aren't ready to execute yet. Good argument, but with
limited applicability. Many persistence systems are transparent and don't have
methods like that.

(3) The third argument is validation. Most business beans, it is posed, do not know
how to validate themselves, and they especially don't know how to cope with web
semantics and web validation issues.

<ot> Though, I'm thinking validation is a perfectly reasonable thing for a persisted
object to do. And being able to validate String input, in these days of multi-tier
development, is also a reasonable feature now.

Any bean that might be populated from an external resource, whether it is a


database, XML element, or HTTP request, should be able to validate itself. There's no
telling what happened to its data between sessions. For example, a DBA could have
run a query that changed its state in an unexpected way. Defensive programming
would seem to dictate that a persisted bean must know how to validate (or test)
itself at runtime. This is not a presentation issue, it's a model-state issue. </ot>

(4) The fourth argument is composition. Often a single HTML form is made of
properties that will be used by several different objects. These are more easily
represented by a single object than multiple objects. Nesting objects is an option,
but, in practice, the nested "dotted" syntax can confuse other players, like
JavaScript. Meanwhile, the more objects you nest, the more security issues you
might raise (by exposing business methods that should not be called from the
presentation layer).

I'm still kinda sold on the composition argument. I find that a "data entry object"
does make sense for most complex applications. Often, we need to format the data
in certain ways outside of what the model would expect. We may also need to
provide helper methods to make HTML controls easier to render. And we should
identify the input fields, as opposed to whatever other non-input fields may exist in
the model. In practice, a Data Entry Object becomes a coarse-grained, denormalized
transfer object, where the property userName often equates to something like
user.Name in the model. The DEO can be an interface defined in the business layer
but implemented in the presentation layer.

Meanwhile, I find that my ActionForms often need properties that don't exist in my
persistence model, but do exist in my data access signatures. So the Data Entry
Object is a place where you can encapsulate what you need for

• persistence objects (straight data)


• data access methods (filters)
• presentation objects (formatting)

To help get from the ActionForm properties to the persistence properties, I'm starting
to think about a fancy version of BeanUtils.Populate that would automatically map
patterns like userName to user.Name if you passed it a set of target beans. It might
also take a configuration to map coarse names to fine names, the way Hibernate
maps properties to columns.

(I'm actually starting to think in terms of a master XML element that could be used
to map DEOs (ActionForms) to persistence objects to relational tables, with the
appropriate validations between each layer. This might be used to create separate
XML documents for each gizmo you are using [Validator, Hibernate, Struts]. The
convenience of a desktop database dialog with the power of native tools.)

So, for now, I generally recommend defining a coarse-grained ActionForm with all
the input properties that you application uses. (For larger applications, it may be a
module or other logical subset of the application.)

For each set of validations (or "forms"), define a different formbean. If you are using
the Struts Validator, you don't have to define a new subclass (the validator goes by
the formbean/attribute name). Otherwise, you can subclass the "properties"
ActionForm and define a validate method.
This approach lowers maintenance, maximizes coherence, and minimizes coupling.
Achieving high coherence and low coupling is the primary goal of a MVC architecture.
There is still duplication between data-entry and model properties, but it is
manageable.

The "duplication" is even *useful* for Test Driven Design. You can start by designing
the application using coarse-grained ActionForms and let the UI tell you what data
access signatures you need. Your object graph or database schema can then live on
the other side of your data access signatures and be whatever they need to be. This
gives you the chance to design the model (object/database layer) after you have
tested what the client/UI actually needs.

In practice, we often design the model too early and end up writing code that we
never use. A coarse-grained data entry object lets you design and test the UI before
mucking about with the business object or db layer.

In the Action, you can use BeanUtil.copyProperties to beam over any properties that
happen to match. For those that don't, you may have to resort to a manual transfer.
[person.setName(actionForm.getPersonName)] Some people use an adaptor or data
mapping object here to encapsulate the dirty work. We probably need a better
general purpose utility here, like BeanUtils.mapProperties, or something.

Often, there is a relationship between the form validations and your use-case (or
client story). It can be useful to name your formbean after the underlying use case,
to help keep everything straight. I tend to use generic names for my ActionForm
classes (like FormProperties and FormHelper), but very specific names for formbeans
(like "permit_search_all" and "permit_store"). This keeps the formbeans/validations
aligned with the use-cases they represent (store a permit, search all the permits).

(See also "Wither ActionMappings" <http://www.mail-archive.com/msg57843.html>)

HTH, Ted.
---
Struts in Action

How do ActionMappings fit into the overall architechture of an application?


Location: http://www.jguru.com/faq/view.jsp?EID=1069990
Created: Mar 26, 2003
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

Whither ActionMappings?

We write applications to do things for people. We might say, for example, that we
want the appication to create a mail-merge job for us. Some developers call these
top-level tasks "client stories". In practice, to do a big job like this, an application will
need to take several smaller steps. We'll need to obtain the information from the
user about which mail-merge job to create. We'll need to find the items to merge.
We'll need to put the items together with a template, and we'll need to present the
result back to the user. Some developers call these smaller tasks "use cases". To
complete a client story, we usually chain several use cases together. A chain of use
cases is sometimes called a workflow.
Before doing any thing for us, most applications wait to be asked. When we ask the
application to do something, we usually need to provide a variety of details. If we
ask the application to store a name and address, we need to provide the name and
address to go along with the request.

HTML Forms

A web application collects such details through a HTML form. Under the hood, a
HTML form submits a request to something called an "action". The action is a
identifer that the web server can use to route the request to whatever software is
suppose to handle it. The HTML specification does not much care what software is
used to handle the request. It simply gives us a place where we can invoke the
software we want to use.

Action Handlers

The simplest handler for an action is another HTML page. This doesn't accomplish
much by itself, since a standard HTML page is static. Another simple way to handle
an action is to install scripting software into your web server. This includes programs
like Perl and Python. The server gives the request to the scripting software, and the
scripting softare returns a response. The server sends the response back to the web
browser (or other client).

Usually, the response will be in the form of another HTML page. Here, we might have
a form action like action="/scripts/merge-form.pl". The HTML page returned by such
a script may not exist as a separate file. The script can generate it "on the fly".

Server Pages

A more sophisticated way to handle an action is with a server-page. The software for
handling the server-page is also installed into the web server. When a request for a
certain type of page, say one matching the extension .jsp, comes along, the server
passes the request to the server-page handler. The handler calls upon the page much
like a script. The request acts as input to the server-page, and the page renders a
response, just as scripting software would. Here, we might have a format action like
action="/pages/merge-form.jsp".

Servlets

Java web applications can also use servlets. A servlet is a binary Java class. After
installing the servlet handler (or "container"), you can register the servlet to handle
requests that match a certain pattern. These might look like server pages (*.do), or
like a sub-directory (/do/*). As with the other methods, the web server hands the
request to the servlet, and the servlet hands back a response. (The web specification
requires a response for every request.)

Most elements in a servlet class are there to support getting a request and returning
a response. When Java developers write servlets, they will usually subclass a working
servlet and add one relatively small method for doing some certain thing. Usually
this certain thing corresponds to handling the input from a particular HTLM form.
When this is true, a developer could register the servlet under a concrete identifier,
rather than a pattern. This servlet would then handle one specific request (or
"action").

Some servlets, like the Struts ActionServlet, let you put this specialized method into
another Java class alogether. The ActionServlet is registed to handle all the requests
matching a pattern. Each specific request (or "action") can be assigned to a Java
class. Since these classes are most often called when a HTML form is submitted,
Struts calls these "Action" classes.

ActionMappings

Struts keeps the list of action identifiers (or "paths") and their corresponding Action
classes in a collection called the ActionMappings. Each entry in the collection is an
ActionMapping object. You could create the ActionMappings collection using a Java
class, but that's a lot of work. Struts can load the ActionMappings at startup time by
reading a configuration file written in XML. (The servlet container uses a similar file
to load the Java servlet classes.)

FormBeans

HTML forms often include several bits of information. A form that is adding a record
to a database might include a dozen fields or more. The Java servlet container turns
the request into a Java object which it passes along to the appropriate servlet. Struts
in turn passes the request object to the Action class. You can look inside this object
and get the names of every field submitted with the request and then also ask for
the corresponding value. But this too is a lot of work.

Most Java application now use JavaBeans to represent fields like a name and
address. A reasonable thing for a web developer to do is create a JavaBean with
properties that match the attributes they expect a form to submit. If you create a
JavaBean to match the HTML form, Struts can populate it for you automatically.
Since this is the form that you submit with an action, Struts calls them ActionForms.

Validation

In practice, many HTML forms reuse the same set of fields. A developer can often
create a single ActionForm that can be used with several different actions. To make
the ActionForm's easier to reuse, Struts provides a FormBean class in the
configuration file.

Web developers have to be very careful about the information that is passed to their
application. It is very easy to for people to create a request that looks like it came
from your form. But it could contain any sort of data whatsoever. The data may not
be what your application expects. It is very important that web developers validate
input before letting it into an application.

Accordingly, the Struts ActionForm includes a validate method. Developers can use
this to test the input. If the input cannot be used, the method can return a list of
messages. Struts then forwards the request, including the ActionForm object, back to
an input page. The Struts tags can redisplay the data from the ActionForm, along
with the messages, so the user can correct the errors and try again.
FormBean Names

The input page may contain more than one form. This means that Struts can't save
the ActionForm under a constant name. To avoid collissions, each form (or action)
should be able to have a name of its own. To help you manage an ActionForm's
logical name, Struts provides a form-bean class in the configuration file. Each form-
bean has a unique name and a property to indicate the ActionForm type. If two
forms will appear on the same page, but can share the same ActionForm class, you
can create two form-beans with different names but the same ActionForm type.

The (optional) Struts Validator uses the ActionForm attribute name to identify which
validation to use with a request. When validate is called, the ActionServlet passes
along the ActionMapping as part of the signature. The validator looks up its own form
for that attribute and applies the appropriate validators.

Action Stories

In practice, the ActionMapping attribute, or form-bean name, is identifying the use-


case underlying the Struts action. The form-bean exposes the set of fields the use-
case needs. The validator-form confirms that all the fields are "present and
accounted for". The Action class associated with the same attribute provides the link
between the web presentation layer and your application's business logic.

If you are designing your application first, and then attaching it to Struts, a sound
approach is to use the ActionMapping attribute to link your use case with the Struts
ActionMapping and the corresonding HTML form.

To provide the best flexibility, the HTML form's action attribute is not directly linked
to the ActionMapping's path property. It is tempting to consider using the same
token for the ActionMapping attribute and path. But the path is used as an URI,
which may have "business requirements" of its own. The URI paths might have to
follow a certain pattern to fulfill security requirements. Since you do not want web
requirements to trickle up to the business tier, it's best to use different tokens. You
might start out with the pair being quite similar (like "/permit/search" for the path
and "permit_search" for the name), but eventually you might need to change one
but not the other.

Conclusion

When designing the presentation layer, consider form-beans and their attributes as
an embodiment of your application's use-cases or stories. Rather than use these as
"throw-away" names, link them into your overall architechture. This helps you
visualize how an request progresses from the browser, through your controller, up to
your module, and back again.

HTH, Ted.

--
Ted Husted,
Struts in Action
struts GenericDataSource Just a general question - I'm building an
application that will run stand-alone, not in an application server. I need to
manage some database connections. Is the struts GenericDataSource a
good candidate to do this for me? I basicly just need a connection pool from
where I can get connections and then return them to optimize performance.

If this struts class is not a good candidate, can someone recommend a


similar pool-manager that is lean and mean and easy to use?

Thanks!
Location: http://www.jguru.com/faq/view.jsp?EID=1069993
Created: Mar 26, 2003
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by Charl Gerber
(http://www.jguru.com/guru/viewbio.jsp?EID=976214

The Struts 1.0 GenericDataSource is not a good candidate for a production server. In
Struts 1.1, the Commons DBCP is used istead, which is a good candidate for a
production server. (You can also use the DBCP in Struts 1.0 by specifying the type
and including the Commons JARs.)

Another popular choice is Poolman. It's not under active development, but I believe
you can still download it from SourceForge. Poolman is also very easy to use outside
of Struts.

Many containers also offer support for connection pools. The one that ships with
Resin is quite good. The later versions of Tomcat bundle the Commons DBCP.

Regardless of what pool you use, a good practice is to hide it behind some type of
adaptor class of your own (often a singleton), to make it easy to change later. So
your classes call your adaptor, and your adaptor calls whichever pool you are using.

A neat and often-overlooked aspect of the Struts DataSource manager is that it


supports loading multiple connection pools and giving each a name. So you might
have one pool for internal use and another for public use. This way, the public
connections can't swap your administrative access to the application. Each pool could
also have its own login, and therefore different rights to the underlying database.

HTH, Ted

--
Ted Husted,
Struts in Action

Comments and alternative answers

GenericDataSource and CommonDBCP


Author: Sobha Tammana (http://www.jguru.com/guru/viewbio.jsp?EID=1077609),
Apr 18, 2003
Currently, my application is using database connections (JDBC) and I am able to
connect. When I use the struts GenericDataSource (I have Struts 1.0) in my struts-
config.xml file my application does not even function. I get the error saying that it
could not find the action mappings and action forwards. I followed the examples from
the book. (Mastering Jakarta Struts) I even tried downloading Commons DBCP jar
file and including the type in the xml file but I get errors. What I am missing. ??

Thanks
Sobha.

Re: GenericDataSource and CommonDBCP


Author: Srinivas K (http://www.jguru.com/guru/viewbio.jsp?EID=1175432), Jun
1, 2004
I am also getting the same problem. if you solved the problem, can you provide
the solution ?

Thanks & Regards


Srinivas

Re[2]: GenericDataSource and Struts 1.0 and Struts 1.1


Author: TRAN the lam
(http://www.jguru.com/guru/viewbio.jsp?EID=1186578), Jul 16, 2004
int i=1;

with Struts 1.0 and jdbc i'am use GenericDataSource


not in struts-xml, but in Client.properties

my Client.properties
instanceBd=oraID
userPasswd=xxx/yyyy
maxCount=20
minCount=19
port=1521
driver=oracle.jdbc.driver.OracleDriver
url=jdbc:oracle:thin:@serverName:port:instanceBd

then, on my code i have init (struts 1.0 or struts 1.1):

GenericDataSource ng = new GenericDataSource ();

ng.setUser (mprop.getUserBd());
ng.setPassword (mprop.getPasswdBd());
ng.setUrl (mprop.getUrl());
ng.setDriverClass(mprop.getDriverClass());
ng.setMaxCount(mprop.getMaxCount());
ng.setMinCount (mprop.getMinCount());
ng.setDescription("jdbc OracleDriver");
ng.setAutoCommit(true);
try { ng.open(); } catch (java.sql.SQLException e) {
}

in business logic (or pool) :


Connect cn = ng.getConnection();

it's work.

with struts 1.1 , struts-legacy.jar is necessy for this


codes.

it's work.

thank.

I have a jsp associated with an ActionForm. I want a parameter passed in


the url become an hidden field of the actionForm. ex:

I call /form.jsp?para=123

the result is
<form action="/betaForm.do">
<hidden name="para" value="123">
</form>

Is-there an easy way to do that ?

Thanks, Franck
Location: http://www.jguru.com/faq/view.jsp?EID=1071584
Created: Mar 31, 2003 Modified: 2003-04-09 02:37:52.015
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

Struts uses the ActionForm to encapsulate whatever dynamic properties your


presentation page needs. The best practice would be to make para an ActionForm
property and to link to an ActionMapping rather than directly to a JSP. If you were to
do that, then the ActionServlet would capture the parameter and make it a property
of the ActionForm (assuming there is a para property on your ActionForm). You can
then use the Struts HTML tags to render the para value.

So

(1) Create a para propery on an ActionForm.


(2) Associate that ActionForm with an ActionMapping (e.g. /form).
(3) Have the ActionMapping forward to your JSP.
(4) Link to form.do (or /do/form) rather than form.jsp.
(5) Use the standard Struts HTML tags (or Velocity directives) to render the para
field.
Alternatively, you could use the bean:parameter tag to convert the parameter into a
bean and then use bean:write. But it would be better to put the para property on the
ActionForm (where it belongs).

HTH, Ted

--
Ted Husted,
Struts in Action

I have an application which has around 30 forms.We are using dyna action
forms. I have one action which has to be called from all these 30 forms. So
do I need to have to need 30 mappings in the config file for each form? How
will I handle that.. Thanks for the help, Manoj.
Location: http://www.jguru.com/faq/view.jsp?EID=1071590
Created: Mar 31, 2003 Modified: 2003-04-09 02:37:19.435
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

It mainly depends on the validation needs. In practice, you do need an action-


mapping each distinct validation that Struts must handle itself. Each of these action-
mappings then need either a ActionForm or a Validator form to provide the validation
behavior.

If you are using DynaActionForms, then you probably want to use the Struts
Validator. You can create a Validator form for each validation instance. Then set the
attribute property of the ActionMapping to match the Validator form name. The
action-mapping can then all share the same form-bean (but validate a different set
of properties). The DyanActionForm may define properties that some of the forms
don't use, but that does no harm. (See also "Coarse-grained ActionForms").

If you were using conventional ActinForms, then you could create a base ActionForm
with all the properties that your forms needed, and then a subclass for each
validation. Then, instead of creating Validator forms you could create a form-bean for
each validation instance.

HTH, Ted

--
Ted Husted,
Struts in Action

Comments and alternative answers

Using attribute property in action element


Author: Ashok Shankarnarayan
(http://www.jguru.com/guru/viewbio.jsp?EID=1084898), May 15, 2003
Ted,

Let's say I have an ActionForm, say BaseForm, with several properties. And Form1
and Form2 are subclasses of BaseForm that override the validate() method to validate
different sets of properties.

Per your suggestion, then

<form-bean name="baseForm" type="BaseForm"/>


<form-bean name="form1" type="Form1"/>
<form-bean name="form2" type="Form2"/>

<action attribute="form1" name="baseForm" ....>


<action attribute="form2" name="baseForm" ....>

Is this what you're suggesting? If not, can you give a simple example.

My objective is to avoid using conditionals within validate() method to validate sets


of properties based on which page is currently being processed.

Thanks

Re: Using attribute property in action element


Author: neal ravindran (http://www.jguru.com/guru/viewbio.jsp?EID=17737), Jul
22, 2003
I use this in my struts file and works fine

<action path="/Edit1" type="com.doclink.insurance.struts.AddInsuranceAction"


name="addInsuranceForm" scope="request" input="/insurance/jsp/edit2.jsp">

and also this

<action path="/Edit2" type="com.doclink.insurance.struts.AddInsuranceAction"


name="addInsuranceForm" scope="request" input="/insurance/jsp/edit2.jsp">

The difference is in the path and input attributes. I use HashMap in my Action
form(not set and get methods for each field in form)

Re[2]: Using attribute property in action element


Author: Navier Stokes
(http://www.jguru.com/guru/viewbio.jsp?EID=1081919), Jul 22, 2003
Hi Neal: how do you use HashMap in your Action form and have form data
being populated to the form? What's the advantage of it? thanks!

Re[3]: Using attribute property in action element


Author: neal ravindran
(http://www.jguru.com/guru/viewbio.jsp?EID=17737), Jul 22, 2003
Given below is the code. No tedious get and set... And if your form
changes no recode of this(JBuilder 8 can make the one with getter and
setter automatically, I hear, btw) But maps are easier if you ask me.

package com.doclink.insurance.struts;
import javax.servlet.http.HttpServletRequest;
import org.apache.struts.action.ActionForm;
import org.apache.struts.action.ActionMapping;
import java.util.*;
public class AddInsuranceForm extends ActionForm
{
private Map values = new HashMap();
public void setValue(String key, Object value) {
values.put(key, value);
}
public Object getValue(String key) {
return values.get(key);
}
public void reset(ActionMapping mapping, HttpServletRequest request)
{
values = new HashMap();
}
}

===============Access========
You access in Action class execute function like so:- AddInsuranceForm
addInsuranceForm = (AddInsuranceForm) form;
String typeIdStr=(String)addInsuranceForm.getValue("typeId");

=============In the HTML form=======


In the html form you define it so(I show only a hidden element...others are
similar):-
<html:hidden property="value(typeId)" value="<%=typeId%>" />
Note the name..and it has to be so named.

Somebody in a forum told me that it can be slower than the one with getter
and setters...but hey who wants to code all that for every field ;)

How to validate a hashmap using Struts Validator Framework


Author: Niraj Jalan
(http://www.jguru.com/guru/viewbio.jsp?EID=1165540), Oct 2, 2004
Hi, How can one validate a hashMap defined in DynaAction form using
the struts validator framework. Scenario: I have a hashMap with some
numbers mapped to an id. I want to validate these number as intergers.
How can i do it? Thanks, Niraj.

Re: Using attribute property in action element


Author: michele ling (http://www.jguru.com/guru/viewbio.jsp?EID=1170599),
May 13, 2004
I have the same question on this. please give some code. Thanks

Security issues around extra form-properties in form-bean


Author: A K (http://www.jguru.com/guru/viewbio.jsp?EID=1217464), Dec 21, 2004
Hi Ted, I would like to ask about the security implications of having extra form-
properties in a form-bean shared among single action-mappings. Here is my proposed
scenario: User A can update field1 and field2. User B can only update field1.
update.jsp dynamically shows field2 based on permissions. update.jsp has one form-
bean associated with it containing both field1 and field2. The form is mapped to a
single UpdateAction. If I don't do permission checking in UpdateAction, wouldn't
User B be able to update field2 by submitting a properly formed post outside of the
view. How can I avoid this without creating multiple actions? Thanks AK

Exceptions that occur in an Action class can be catched in the Action class or
handled by registered handlers, in the struts-config.xml file, that route
control to specified error pages.

Exceptions that occur in the JSP pages can also be routed to specified error
pages, this is declared in the web.xml file. But this only seems to work with
'standard' JSP pages. Those JSP pages that use Tiles won't go to the error
page given in web.xml.

Is this a known problem or am I missing something?

jecs
Location: http://www.jguru.com/faq/view.jsp?EID=1071592
Created: Mar 31, 2003 Modified: 2003-04-09 02:36:33.413
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042)

It depends on when the error occurs. When you are using Tiles, the response is
rendered tile-by-tile. Once the response starts to render, control cannot be forwarded
to another page. So with Tiles, you may also see an error message for one tile, while
the others render just fine.

But, if you do not have any business/system logic in your tiles, this type of error
should not happen in production. You should be able to detect any runtime problems
in your Action and forward to an error page yourself, without relying on the
container's assistance.

HTH, Ted

--
Ted Husted,
Struts in Action

Comments and alternative answers


Catching exceptions from a Tiles component
Author: Christoffer Soop (http://www.jguru.com/guru/viewbio.jsp?EID=1074744),
Apr 9, 2003

As a note to Ted's answer: would it not be nice to have slightly more informative error
messages if something unforseen goes wrong when rendering a Tiles component?

I agree that exceptions not properly handled in the actions ought not to occur in
production, but sometimes they do. Even if care has been taken to separate business
logic from presentation. Thus, I would be happy to see a special error-tile that gives
control to the developer what should be displayed when that error that is not supposed
to happen, happens.

/Christoffer

Can you tell me more about how to handle the exception that occur in the jsp,
and how to route to a specific page when that happens?
Author: Alka Sinha (http://www.jguru.com/guru/viewbio.jsp?EID=1079931), Apr 28,
2003
Can somebody tell more about how to handle the exception that occur in the jsp, and
how to route to a specific page when that happens?

Re: Can you tell me more about how to handle the exception that occur in the
jsp, and how to route to a specific page when that happens?
Author: prashant jani (http://www.jguru.com/guru/viewbio.jsp?EID=100991), Sep
17, 2003
u can use the jsp error directive isPage="false"
errorPage="somePage.jsp"

Jani

Re[2]: Can you tell me more about how to handle the exception that occur
in the jsp, and how to route to a specific page when that happens?
Author: LAKSHMINARASIMHAN KRISHNASWAMY
(http://www.jguru.com/guru/viewbio.jsp?EID=1136805), Jan 7, 2004
whether it is the only thing to be changed for routing to error.jsp or else
whether we will have to do some thing in Action Classes and Action Form?

Re[3]: Can you tell me more about how to handle the exception that
occur in the jsp, and how to route to a specific page when that
happens?
Author: prashant jani
(http://www.jguru.com/guru/viewbio.jsp?EID=100991), Jan 7, 2004

The above script written in the jsp page can be also used
for a jsp page which is not a part of any framework.
This allows the jsp to redirect to an error page.

In case, you are using struts exception handling can be done


by two ways:
1> Declarative (using struts features via struts-config.xml)
2> Programmatic (using the usual try-catch exception
handling)

I suggest you read the documentation on struts.

regards
Jani

Two years later...


Author: P B (http://www.jguru.com/guru/viewbio.jsp?EID=1239318), Apr 18, 2005
Its been two years since this thread started and I notice that this scenario still pops up
with a minimal amount of understanding or helpful fixes/workarounds.

I find Teds first paragraph to be right on the money, but while paragraph two
theoretically seems correct, it is just not the case. For example, if session data was
used to populate a page1, then later cleared when the user was doing another task in
page2. If the user clicks their back button, page1 will throw an exception (null pointer
or null reference?).

The only way I found to avoid this error page situation is to design the tiles slightly
differently from the start. For example, many applications look like this...
page1.jsp

<tiles:insert page='/tiles/page_template.jsp' >


<tiles:put name='header' value='/tiles/header.jsp' />
<tiles:put name='content' value='/auth/page1_content.jsp' />
</tiles:insert>

page_template.jsp

<tiles:insert attribute='header' />


<tiles:insert attribute='content' />

So when the error occurs in the content page, no error page will display because the
header already wrote to the response/stream. If you modify your initial design to
something more like the following, your header and body will be part of the same
output and your error page will work properly (not to mention reduce the number of
jsps in an app by about 50%)...
page1.jsp

<tiles:insert page="/layouts/page_template.jsp" flush="true">


<tiles:put name="header" value="/layouts/header.jsp"
type="page"/>
<tiles:put name="body" type="string">
<!-- Page content : start -->
<!-- Page content : end -->
</tiles:put>
</tiles:insert>

page_template.jsp

<html:html>
<head></head>
<body>
<!-- 1st outside table (entire page)-->
<!-- tile that holds header content of page -->
<tiles:insert attribute="header" />
<!-- tile that holds body content of page -->
<tiles:insert attribute="body" />
</body>
</html:html>

Re: Two years later...


Author: sri rao (http://www.jguru.com/guru/viewbio.jsp?EID=1240694), Apr 24,
2005
Hi PB, Can you please help me in finding the solution. I was uisng Tiles with
Struts and servlet. With Struts is working fine and when i request goes to servlet i
was getting IllegalStateException and the response is in Committed state. In ur
example u r saying that to use <!-- Page content : start --> <!-- Page content : end
--> what is this? can you please give full example. Thnaks and regards. Sri

Opening new window or going back

I have a form (reportForm) with two different buttons. "Print" and


"Cancel". When clicking 'Print' I want to open a new window, that prints a
report using a bean set by 'action' of 'reportForm'. If cancel is clicked I want
to back a page. If I set the target to "_blank" in reportForm, clicking on
either of the buttons opens a new window? Any pointers? Regards, Harsh
Location: http://www.jguru.com/faq/view.jsp?EID=1074755
Created: Apr 9, 2003
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by Harsh Daharwal
(http://www.jguru.com/guru/viewbio.jsp?EID=1074636

To go back a page, you can use a standard JavaScript button.

<input type='button' onclick='history.go(-1);' name="button"


value="PRINT" />
To popup another window, you can pass whatever parameters you need from the
bean to the JavaScript. You can also use custom tags within the JavaScript to render
URIs and such.
Here, if the "View Script" link is clicked, we open a window unto the "itemScript"
forward, which corresponds to the Struts path "/do/item/script/View".

<a href='javascript:doScript(<bean:write name="itemForm"


property="item"/>)'>View Script</a>

<!-- ... -->

<script>
function doScript(aItem) {
aBase = '<html:rewrite forward="itemScript"/>';
doOpenRemote(aBase + '?item=' +
aItem,'preview','*','600','scrollbars','form');
}
</script>

<script>
function doOpenRemote(aURL, newName, aHEIGHT, aWIDTH, aFeatures,
orgName){
if (aHEIGHT == "*"){ aHEIGHT = (screen.availHeight - 80) };
if (aWIDTH == "*"){ aWIDTH = (screen.availWidth - 30) };
var newFeatures = "height=" + aHEIGHT + ",innerHeight=" + aHEIGHT;
newFeatures += ",width=" + aWIDTH + ",innerWidth=" + aWIDTH;
if (window.screen){
var ah = (screen.availHeight - 30);
var aw = (screen.availWidth - 10);
var xc = (( aw - aWIDTH ) / 2);
var yc = (( ah - aHEIGHT ) / 2);
newFeatures += ",left=" + xc + ",screenX=" + xc;
newFeatures += ",top=" + yc + ",screenY=" + yc;
newFeatures += "," + aFeatures
};
var newWin = openWin(aURL, newName, newFeatures, orgName);
newWin.focus();
return newWin
}
</script>

<script>
function openWin(newURL, newName, newFeatures, orgName) {
var newWin = open(newURL, newName, newFeatures);
if (newWin.opener == null)
newWin.opener = window;
newWin.opener.name = orgName;
return newWin
}
</script>
In the new window, to let them print or close the window, again you can just use the
typical JavaScript solutions:

<input type='button' onclick='javascript:window.print();' name="button"


value="PRINT" />
<input type='button' onclick='javascript:window.close();' name="button"
value="CLOSE" />
Note that we don't bother with the Struts tags here, because they provide no added
value. POH (Plain Old HTML) works just fine =:0)

HTH, Ted

--
Ted Husted,
Struts in Action

Comments and alternative answers

Opening New Window [Contd.]


Author: Harsh Daharwal (http://www.jguru.com/guru/viewbio.jsp?EID=1074636),
Apr 9, 2003

Thanks for the response.

I've seen this code snippet on your website and Struts In Action as well. Not sure if it
solves my problem.

• Back button defined the way you described asks me to reload the page, which
has dynamic content, and expires once I move to current page
• ViewScript example you've given is for a 'link'. I'm not sure how to attach it to
a button.

Regards, Harsh

Iterate Increment

Hi by default logic:iterate will increment the loop by 1. What do i need to do


if i need to increment the loop by 2?
Location: http://www.jguru.com/faq/view.jsp?EID=1074765
Created: Apr 9, 2003
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by Ramesh Shanmugam
(http://www.jguru.com/guru/viewbio.jsp?EID=474439

Iterate is not a loop. It passes over the items in a collection. If you don't want to
process all the items, don't put them in the collection to begin with =:0)

Though, you could do something with a scriptlet so that it would not handle some
items.

<% int i = 0; %>


<logic:iterate id="lot" name="list" >
<% i++; if ( i % 2 == 0) { %>
<bean:write name="lot" property="name"/>
<% } else { %>
<!-- skipping alternate lot -->
<% } %>

In Struts 1.1, there is an indexId bean provided by iterate that you could test instead
of rolling your own counter.

But this sort of thing is generally not recommended! Your Action should
determine precisely what data the page needs and create the appropriate collection
for the circumstances. The page should then just be able to render whatever it is
given. If a page has to pick-and-choose anything, then the Action is not doing its job
=:0)

Depending on your needs, you might also want to create a custom tag that applies
whatever business logic you need. Struts provides a handy set of generic tags, but
the idea behind JSP tags is that you can write whatever tags you need for your
particular circumstances.

HTH, Ted

--
Ted Husted,
Struts in Action

Comments and alternative answers

Using indexID on logic:iterate and then testing the index value


Author: David Anthony (http://www.jguru.com/guru/viewbio.jsp?EID=1100353),
Aug 25, 2003
Not being able to test the indexId value from a logic:iterate within the body iteration
and having to resort to scriptlet code is unacceptable! The logic:equal, for example,
should contain an indexId tag that names the indexId defined on the iterate. This
named index would then be compared against the value in its value tag (0, 1, 2, etc.)
With something like this, you would at least have a "clean" Struts way of knowing
where the hell you are in the iteration body. Not good!

Struts & Reports


Author: Donnie Molleson (http://www.jguru.com/guru/viewbio.jsp?EID=1119868),
Oct 6, 2003
I am new to the Struts world. I am looking for a "standard" for creating user reports
within the Struts framework. Any suggestion?

No errors are forwarded when redirect is set to true I use the following code
to send a forward:

forward = mapping.findForward("cancel");
if (forward!=null) {
ActionErrors errors = new ActionErrors();
errors.add(ActionErrors.GLOBAL_ERROR, new ActionError("error.rtzu"));
saveErrors(request,errors);
return forward;
}

When I set redirect to true the errors aren't displayed in the jsp page.
I've tried both redirect methods:
forward.setRedirect(true);
and
redirect=true (in forward)

How to get errors visible with redirect=true ?


Location: http://www.jguru.com/faq/view.jsp?EID=1078429
Created: Apr 22, 2003
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by Kirschmann Yves PREMIUM
(http://www.jguru.com/guru/viewbio.jsp?EID=931345
The framework stores the errors in the request, and so when you redirect, they
disappear. The usual work around is to save the ActionErrors to the session yourself,
and then move them from the session back to the request in the Action to which you
are redirecting. If you do a lot of this, the routine could be made part of a base
Action, a servlet subclass, or RequestProcessor in Struts 1.1.

HTH, Ted.

Comments and alternative answers

html:errors taglib
Author: Radoslaw Wisniewski
(http://www.jguru.com/guru/viewbio.jsp?EID=1088059), May 26, 2003
html:errors reads ActionErrors from session context too, so you do not must to move
errors back to request.

Re: html:errors taglib


Author: stefan berger (http://www.jguru.com/guru/viewbio.jsp?EID=1088950),
May 28, 2003
How u write back the errors into session ? Small example pls. I have the same
problem with redirect=true and loosing my errors. Thanks

Re[2]: html:errors taglib


Author: Saravanan Jayachandran
(http://www.jguru.com/guru/viewbio.jsp?EID=91462), Jun 19, 2003
Just override the saveErrors method of Action class in your BaseAction.
if ((errors == null) || errors.isEmpty()) {
session.removeAttribute(ERROR_KEY);
return;
}
session.setAttribute(ERROR_KEY, errors);
HTH, saravanan

Re[3]: html:errors taglib


Author: Navier Stokes
(http://www.jguru.com/guru/viewbio.jsp?EID=1081919), Jul 22, 2003
I think we need to move the errors from session to request is because there
is no code to remove the errors in session, and it will stay in session until
changed?

Re[4]: html:errors taglib


Author: Muhammad Younas
(http://www.jguru.com/guru/viewbio.jsp?EID=1156063), Mar 20, 2004
Yes, we cannot remove errors from session but logically we can do this.
How ?. If you set them null in your session object, you can say that
they are removed.

Re: html:errors taglib


Author: kumar vasu (http://www.jguru.com/guru/viewbio.jsp?EID=1236253), Apr
2, 2005
ActionErrors errors = new ActionErrors();
errors.add(ActionErrors.GLOBAL_ERROR, new
ActionError("errors.olpm.emptyList")); saveErrors(request, errors);

Another alternative for exception handling


Author: Trevor Harmon (http://www.jguru.com/guru/viewbio.jsp?EID=1246457),
May 31, 2005

If the error you are handling is due to a specific exception, one that has a specific
error message that you want to display using <html:errors>, then you can simply add
an <exception> tag to the <action> declaration in your struts-config.xml, like this:

<exception
key="error.message"
type="net.sf.hibernate.exception.ConstraintViolationException"
path="/administration/user-accounts/add-user/index.jsp"/>

Qus:Struts with Ejb.


Author: vijendra singh (http://www.jguru.com/guru/viewbio.jsp?EID=1255427),
Jul 28, 2005
Qus:If somebody wants to use struts with Ejb then as i know in struts-config.xml
we do datasource declaration but application server requires Its own
congigauration for database.Then how do we procede.
indexed properties I am confused by the indexed properties of Struts. What
I wanted to do is iterate through a collection of String in jsp and for each
element there is a radio button with value= that of the element.

The generated HTML seems to have the name of the radio button same as
the name of the element.
Location: http://www.jguru.com/faq/view.jsp?EID=1078445
Created: Apr 22, 2003
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by sender jones
(http://www.jguru.com/guru/viewbio.jsp?EID=1067664

Radio tags are usually rendered as such

<html:radio property="bidType" value="1" />Bid up to this amount on my


behalf

<html:radio property="bidType" value="2" />Bid this exact amount


The radio tag then "selects itself" if the property matches the given value.

In Struts 1.1, a idName property was added, so you could provide the values from a
collection. Of course, you also need to provide labels, so you need to use some type
of label -alue collection.

I don't have an example handy, but I *believe* the code would go something like
this:

<logic:iterate name="radioLabelValues" id="button">


<html:radio property="bidType" idName="button" value="value"
/><bean:write name="button" property="label"<br>
<iterate>
Let me know if that actually works =:)

HTH, Ted.

Comments and alternative answers

There seems to be a problem with dynamic arrays.


Author: barry raczkowski (http://www.jguru.com/guru/viewbio.jsp?EID=1207559),
Oct 27, 2004
Hi Ted; I've read Struts in Action it was pretty good. I have impelemented a dynamic
indexed form. I am able to get the form to load the date in an iterator by overriding
the get(name,index,value); However, when I submit the form I am not able to pull the
customer changes off form the form. I must use the request object to pull the values
from the form.

Preventing users from accesing action. I am writing a web app to manage


administrators and profiles.
Administrators may access to the web app based on the profiles they have.
The profiles, determine which pages the administrator might access.

The profiles, and authorizations, might change online during work, so I need
to check authorization to access a page (Action) on each access.

If I understand correct, then, the actionServlet, first process the form bean,
and then the action..

But, if the user is not authorized to access a specific page (Action), I need
to forward him to an UnAuthorized error page, before thr formAction bean is
filled.

Where in the life cicle of the request and how, do I do that? Thanks. (Sorry
for my English).
Location: http://www.jguru.com/faq/view.jsp?EID=1087081
Created: May 22, 2003
Author: Ted Husted (http://www.jguru.com/guru/viewbio.jsp?EID=462042) Question
originally posed by shmulik shnoll
(http://www.jguru.com/guru/viewbio.jsp?EID=1021099

If you are using Struts 1.1, there is a roles attribute to the action mapping where
you can specify standard JAAS roles. If you are not using container-managed
security, you can create your own RequestProcess subclass, override the appropriate
method to call your security, and then plug in your RequestProcess subclass.

If you are using Struts 1.0, people often write this sort of thing into a standard base
Action class. On entering perform, the Action does a security check on itself, and if it
passes, calls another method with the same signature (like, say, execute).
Otherwise, it forwards off to whereever.

To store the security roles in Struts 1.0, you can add a public properties to your base
Action (like, say, roles), and then use the set-property element to set the roles for
each action.

The perform in your base Struts 1.0 Action could then run the security check if roles
is not null, or skip it if not. If it passes, it can call the other signature.

If you use execute and roles for these extensions, you will also be upwardly
compatible with Struts 1.1. Just be sure to have your execute method return
Exception (which perform can then toss as a ServletException).

HTH, Ted

--
Ted Husted, Struts in Action.

Comments and alternative answers

using filter
Author: Gernot Pfingstl (http://www.jguru.com/guru/viewbio.jsp?EID=231187), Oct
31, 2003
I used another approach for Struts 1.1: I wrote a servlet filter. This filter checks the
users rights and instanciates a HttpServletRequest-Wrapper (use
javax.servlet.http.HttpServletRequestWrapper as base class) which redefines
public Principal getUserPrincipal()
public String getRemoteUser()
public boolean isUserInRole(String role)
So I can use the roles attribute and I'm not required to use container managed security.
Gernot

Re: using filter


Author: shilpa vaidya (http://www.jguru.com/guru/viewbio.jsp?EID=1175883),
Jun 3, 2004
Hi Gernot, Me doing a similar thing.trying to create a filter before request
processor. any amore info on these grounds. shilpa

Method-Level roles attribute?


Author: Anthony Law (http://www.jguru.com/guru/viewbio.jsp?EID=882127), Feb
10, 2004
Hi in Struts 1.1, is there a way to specify role permissions at the method level (kinda
like EJB method level role permission)?

I have a few DispatchAction classes with your typical create/read/modify/delete


scenarios, and I would like Admin roles to have full access to all methods, but User
roles to the Read method only.

Cheers,

Anthony.

Re: Method-Level roles attribute?


Author: Adrian Lanning (http://www.jguru.com/guru/viewbio.jsp?EID=1125230), Feb 22, 2004
Hi!

For per-action roles, overriding the RequestProcessor's processRoles method is very easy. There's
really not much to it although Ted covers it well in his book, Struts in Action (pg. 260). This method
will let you control access to your actions through your struts-config.xml file.

I don't know of a way to use the built in roles permissions to handle method-level security. But you ca
definately do it manually. I mean call a utility function which checks user roles at the beginning of
each method to be secured.

A more elegant solution would be to check out the source to LookupDispatchAction and extend it a
little to lookup role permissions in a class-path-based resource file on a per-method basis. This
centralizes access permissions in a resource file but not in the struts-config.xml file.

Even more elegance might be achieved by extending ValidatorLookupDispatchAction (VLD) to


support per-method roles in the struts-config.xml file itself. VLD allows code like this in the struts-
config.xml file:

<action
path="/Login"
type="com.mycompany.myapp.presentation.action.signup.LoginAction"
name="loginForm"
parameter="action" scope="session" validate="false"
input="input"
className="org.apache.struts.actions.ValidatorLookupDispatchActionMapping"
<set-property property="validateMethod(unspecified)" value="true"/>
<set-property property="validateMethod(add)" value="false"/>
<set-property property="validateMethod(edit)" value="false"/>
<set-property property="validateMethod(delete)" value="true"/>
<set-property property="validateMethod(view)" value="false"/>
<set-property property="validateMethod(prev)" value="false"/>
<set-property property="validateMethod(next)" value="true"/>
<forward name="prev" path=".login" redirect="false"/>
<forward name="view" path=".login" redirect="false"/>
<forward name="next" path=".account" redirect="true"/>
<forward name="input" path=".login"/>
</action>

Where for validateMethod(xxx); xxx = method name.

ValidatorLookupDispatchAction is not part of the main struts release (although I find it extremely
helpful). Brandon Goodin wrote it and I found it purely by chance searching Google for something lik
it. Google it to return 3 results. You can find the source code at [1]. I'm not sure what license it is unde
but I wrote to Brandon asking him if I could use it and he gave me permission to, "do whatever I like"
with it. You might want to write him yourself tho (I'm no lawyer). ;)

I have made a slight modification to the original VLD so that validation rules are applied per-form
rather than per-method as in the original. If you are interested let me know. My email can be found on
my website.

HTH,
Adrian Lanning
http://alanning.freeshell.org

PS. If you actually implement one of the later methods, please send me the source! I'll need it myself
on an upcoming project. ;)

1. ValidatorLookupDispatchAction (vld.zip)
http://phase.ws/struts/
Re[2]: Method-Level roles attribute?
Author: Anthony Law (http://www.jguru.com/guru/viewbio.jsp?EID=882127),
Feb 24, 2004
Great suggestions. The VLD approach looks really interesting. Thanks Adrian!

We use XDoclets heavily & my goal is to have as little custom config as


possible, and also only modify/extend open source code when it's absolutely
necessary.

We're already protecting all Struts Actions & other web resources via a coarse
grain web-security.xml merge file. Looks like the simplest solution is to
continue calling the role check method in my BaseDispatchAction for the
more restrictive methods.

I was hoping I can use XDoclet or a Struts config file to achieve what I want,
but it's not critical. Losing the flexibilty of modifying security roles via XML
config files at deploy time is not an issue for us. If we ever change our security
model, it'll mostlikely require view (ie different ActionForward) & probably
some model changes, which means a full recompile anyways.

Вам также может понравиться