| |||||||||||||||||||||||||||||||||||||||
Introduction
Introduction![]() An overview over the central classes of the Struts framework. ModelActionFormDynaActionFormLose type checking lose the validate method fewer classes, forms are specified as xml may introduce harder to find bugs remember, xml is not a programming language..Form state conversionStruts does not support you in the model aspect of your application. However, Struts encapsulate the model of the webapplication forms in subclasses ofActionForms or by the use of HashMaps (through DynaActionForm). The separation between the webapplication form state and the model state may often map 1:1. There are several
best practices to handle this situation
Controller/ActionAction Mapping
Action node of the structs-config.xml
A typical action declaration for validating a form is
<form-bean name="formExample" type="com.yourcompany.struts.ExampleActionForm"/>
...
<action path="/urlExampleForm" <!-- url in the browser + ".do"
name="formExample" <!-- name of registered form -->
type="com.yourcompany.actions.ExampleAction" <!-- the action dealing with valid forms -->
input="/index.jsp" <!-- page/action to visit upon failure of invalid form validation -->
validate="true" <!-- validate the form automatically before invoking the action -->
scope="request">
</action>
Forward actionYou should never use direct links to other pages. Not only can it break your Struts application (if multiple modules are in play), it is also a direct violation of the MVC architecture. The fundamental philosophy of MVC is that it is the controller that decides what to display on certain events. Thus instead of a direct link to a page, you must set up an action that forwards to that page. The advantage is that later you may find you want certain business logic to be executed upon visiting the page in question. This is possible with this setup. Additionally, using direct li It is not only bad design, but may lead to problems in your Structs application if you use direct linking. Firstly, at some point in the development it may be realized, that an event need Instead use aForwardAction. To link home.do to index.jsp amend struts-config.xml in the following
Include actionInstead of forwarding the request, this action includes the given ressource instead. As discussed in the forward action, you should never refer to jsp pages directly, rather views must be fetched from the controller/actions. In order to include another ressource do the following
DispatchActionWhen an action class is to handle more than one kind of input, you should inherit theDispatcherAction rather than the Action class.
This situation arises, when a form has more than one button, e.g. "edit", "delete" and "add" but you want to centralize the code for these actions in one class.
To use this class take the following steps.
LookupDispatcherAction instead.
ViewTilesInstalling
Defining tiles and extending existing tilesBest usage tilesThe best way to use tiles is
Simple usage tilesThe simplest usage is to create a jsp page that tells at a certain point to insert the set of tiles defined by a certain name in thetiles-defs.xml.
This is unpreferred, as such a page should not be needed at all. Presumably it can be useful for those rare but odd cases that may arise in any software project.
Using CSSUnless you have all your.css files in the root folder (which generally is a bad idea), the you need to specify a relative path
for the location of the css files. Alternatively, you can hardcode a full URL http://www... this however, causes problems if you want
to test offline, have the same application running on several urls or in case you move the application to a different url.
<%@ taglib uri="/tags/struts-tiles" prefix="tiles" %> <html> <head> <style type="text/css" media="screen"> @import "<%= request.getContextPath() %>/styles/styles.css"; </style> <title> <tiles:getAsString name="title"/> </title> </head> Error HandlingError handling is spread out across a number of entries.
Configuration file magic and ModularizationStruts allows you to modularize your webprojects into smaller chunks in two different ways. The simple solution basically allows you to split yourstuts-configuration.xml
into several pieces whilst still having Struts regarding them as one file. The other solution, called modules, allows you to split your application into many name spaces. This allows you to for each module to define
a mapping between a name and a class independently of other modules.
Finally we look at how to significantly reduce the size of your configuration files by the use of wildcards.
Splitting struts-configuration.xmlTo split up yourstruts-configurations.xml into several pieces, all you need to do is to specify those names in web.xml
<servlet>
<servlet-name>action</servlet-name>
<servlet-class>org.apache.struts.action.ActionServlet</servlet-class>
<init-param>
<param-name>config</param-name>
<param-value>
/WEB-INF/struts-config.xml,
/WEB-INF/struts-config-global.xml,
/WEB-INF/struts-config-admin.xml
/WEB-INF/struts-config-reports.xml
/WEB-INF/struts-config-user.xml
</param-value>
</init-param>
</servlet>
The above code has split the config file in 4. One file to
Struts modulesConfiguration file wildcardsLenghty configuration files can be avoided if you stick to a few simple naming rules and wildcards. Below you'll find two actions suffering from the fact that they are almost identical, but being quite spacious.
<action path="/ContractFormHandler_full"
type="foo.action.ContractAction"
name="ContractFormBean"
scope="request"
validate="true"
input="/full.jsp">
<forward name="success" path="/full.jsp"/>
</action>
<action path="/ContractFormHandler_mini"
type="foo.action.ContractAction"
name="ContractFormBean"
scope="request"
validate="true"
input="/mini.jsp">
<forward name="success" path="/mini.jsp"/>
</action>
Using wildcards, these two actions can be merged into:
<action path="/ContractFormHandler_*"
type="foo.action.ContractAction"
name="ContractFormBean"
scope="request"
validate="true"
input="/{1}.jsp">
<forward name="success" path="/{1}.jsp"/>
</action>
A * matches zero or more characters upto a /. If you need to included slashes in your wildcard use ** instead.
The values of the wildcards are accessed by {n} where n is the possition of the wildcard.
Generally, you should refrain from using more than one or two wildcard at any one time to reduce the complexity of reading the config file.
Finally, {0} has a special meaning being the full path.
If more than one <action> matches a request, then its the action without wildcards that takes precedence. After that, its the last defined
action that has precedence.
Struts best practicesDisallow direct access to *.jsp filesA good way to enforce the MVC and in general to ensure the validity of your applications are to disallow direct access to JSP pages outside the webapplication itself. This forces page display to only take place after an action has executed. The following code should be added to youweb.xml. It sets up a role
<security-constraint> <web-resource-collection> <web-resource-name>Deny Direct Access</web-resource-name> <description>Deny access to JSP's by associating them with denied role</description> <url-pattern>*.jsp</url-pattern> </web-resource-collection> <auth-constraint><role-name>Denied</role-name></auth-constraint> </security-constraint> <security-role> <role-name>Denied</role-name> </security-role> Date in actionformIn order to store dates in your forms, your accessor methods must be able to code and de-code Strings into Dates. At first, it may sound as though Struts is missing a vital compontent of supported types. However, the following solution enables the most versatile approach to date formatting and parsing.
public DateForm extends ActionForm {
Date start;
public void setStart(String startDate) {
start = DateFormat.getDateInstance().parse(startDate);
}
public String getStart() {
return DateFormat.getDateInstance().format(start);
}
}
You will most likely benefit from using the helper class DateParser defined in formatting and parsing.
Error messagesA form bean that is missing the attribute+get/set methods "distributorAccount"
avax.servlet.jsp.JspException: No getter method for property
distributorAccount of bean org.apache.struts.taglib.html.BEAN
at org.apache.struts.util.RequestUtils.lookup(RequestUtils.java:968)
at org.apache.struts.taglib.html.BaseFieldTag.doStartTag(BaseFieldTag.java:176)
at org.apache.struts.taglib.html.HiddenTag.doStartTag(HiddenTag.java:123)
at _newreturns._searchPopup1._jspService(_searchPopup1.java:111)
[SRC:/newreturns/searchPopup1.jsp:19]
How to have 2 submit buttons in a formHow to add two submit buttons to a form in struts? Use aDispatchAction as described above..
Often, however, the following hack is used. Just use the <html:submit.../> tag multiple times. Use different
"property" attributes in each tag. In your Action, if the property
associated with an <html:submit... /> tag is not null, then that's the
button that was clicked.
CommentsIf you have any comments to this article, please drop me a mail at firstclassthoughts at gmail dot com please indicate if I can't publish whole or parts of your comment on the site.If you like this site consider Help spread the wordShare this post on your favorite social bookmarking sites:
The most recent contributions 28/07/09 Magic in mathematics II Fun with the number cyclic numbers, and specifically with 142857 as it is the smallest of such numbers. 13/07/09 My top 8 time-saving Firefox shortcuts This article presents my favorite top 8 time-saving shortcuts in Firefox 3.0 and Firefox 3.5. Get to know these and you'll be saving a lot of time. They have been ordered by "the element of most surprise" 20/05/09 Board Game Jungle speed / Arriba Review of the cool game "Jungle Speed" aka. "Arriba". 16/05/09 Danish Twin words "Twin words" are words that not only have multiple meanings, they must be composed next to each other in meaningful sentences. This article explores the concept of twin words. Nothing of interest? Try browsing the entire article archive... | |||||||||||||||||||||||||||||||||||||||