Reality is a perception. Perceptions are not always based on facts, and are strongly influenced by illusions. Inquisitiveness is hence indispensable

Thursday, January 1, 2009

Web development framework - Struts 1 - part2

In this post, we will see some nuances involved in struts-config.xml, as described earlier, struts-config is set of guidelines for actionservlet that help request delegation.

Struts config example


The following xml file illustrates some of the common features.
<?xml version="1.0" encoding="UTF-8" ?>

<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "http://jakarta.apache.org/struts/dtds/struts-config_1_2.dtd">
<struts-config>
<form-beans>
<form-bean name="SimpleFormBean" type="org.ui.beans.SimpleFormBean"/>
</form-beans>
<global-exceptions>
</global-exceptions>
<global-forwards>
<forward name="welcome" path="/Welcome.do"/>
<forward name="success" path="/success.jsp"/>
<forward name="showLogin" path="/csaLogin.jsp"/>
</global-forwards>
<action-mappings>
<action input="/csaLogin.jsp" name="SimpleFormBean" parameter="simpleShow" path="/show" scope="session" type="org.ui.actions.SimpleStrutsAction"/>
<action path="/Welcome" forward="/welcomeStruts.jsp"/>
</action-mappings>
<message-resources parameter="com/myapp/struts/ApplicationResource"/>
<message-resources key="newBundle" parameter="com/myapp/struts/NewResource"/>

<!-- ========================= Validator plugin ================================= -->
<plug-in className="org.apache.struts.validator.ValidatorPlugIn">
<set-property
property="pathnames"
value="/WEB-INF/validator-rules.xml,/WEB-INF/validation.xml"/>
</plug-in>
</struts-config>




The config file is made up of three major aspects: formbeans, action mappings, message-resources. ActionServlet processes the action mappings and identifies the action to be used for the current request. The 'path' attribute influences the decisions. The action element in xml also specifies the target action class in 'type' attribute and form bean to be used using 'name' attribute. The form bean listed in 'name' also listed under form beans element in the config xml file. The class used for bean representation is mentioned here. An action element can also directly map to a html or jsp file.

The action class contract dictates the use of execute() method. (however, using dispatch action forms with parameters, we can call any method of our choice). The form-bean as discussed earlier, is a good candidate for validation actions.

An example of how validations would look.

public ActionErrors validate(ActionMapping mapping, HttpServletRequest request) {
ActionErrors errors = new ActionErrors();
if (getName() == null || getName().length() < 1) {
errors.add("name", new ActionMessage("error.name.required"));
}
if(getNumber() <= 0){
errors.add("number",new ActionMessage("error.posnumber.needed",getNumber()));
}
{
int x = (int)getNumber();
double y = x;
int res = ((Double)y).compareTo(getNumber());
if(res != 0){
errors.add("number",new ActionMessage("error.integer.needed",getNumber()));
}
}
return errors;
}


The jsp file meant to use the errors looks like this:

  <div id="page1">
<html:errors bundle="newBundle"/>
<html:form action="show.do" method="post">
<div class="fields">
<label for="user">USER</label> <html:text property="name" ></html:text>
<html:errors bundle="newBundle" property="name"></html:errors>
<label for="user-id">USER-ID</label><html:text property="number" ></html:text>
<html:errors property="number"></html:errors>
</div>
<span class="buttons">
<html:submit property="submitType" value="submit1"/>
<html:submit property="submitType" value="submit2"/>
</span>
</html:form>

</div>


The attribute bundle="newBundle" is another aspect, the message properties can be customised (one of the starting steps for internationalisation, no we won't be looking at it in this post). We can have as many message/resource bundles as we like. Have a look at struts-config.xml. The bundle attribute in error tags should map to the key attribute given in struts config.

That summarised our discussion on basic struts.

Web development framework - Struts 1 - part1

For web development in j2ee, one needs to know about basic deployment strategy. The 'basic' stuff includes, knowledge of web server and configuration files required by the framework. For servlet/jsp applications web.xml, or deployment descriptor is the key. Production apps have their own framework and come with their own framework (scripts and config files), this is not the objective of this exercise though.

To simplify development, people have been developing utilities. Struts is one such aid. Supported by Apache. This is over and above the basic strategy. Struts dictates that the users provide config file(s). Let us see the various aspects involved in configuration in this blog.

Web.xml


Web.xml is the starting point for any web application. For a struts application the web.xml looks in the following fashion.
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
<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</param-value>
</init-param>
<init-param>
<param-name>debug</param-name>
<param-value>2</param-value>
</init-param>
<init-param>
<param-name>detail</param-name>
<param-value>2</param-value>
</init-param>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>action</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
<session-config>
<session-timeout>
30
</session-timeout>
</session-config>
<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>
<jsp-config>
<taglib>
<taglib-uri>/WEB-INF/struts-bean.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-bean.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/struts-html.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-html.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/struts-logic.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-logic.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/struts-nested.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-nested.tld</taglib-location>
</taglib>
<taglib>
<taglib-uri>/WEB-INF/struts-tiles.tld</taglib-uri>
<taglib-location>/WEB-INF/struts-tiles.tld</taglib-location>
</taglib>
</jsp-config>
</web-app>




To understand the above, one needs to have some know how of relation between: servlet-class, servlet-name and servlet-mapping. They are supposed to provide degrees of freedom to various stakeholders namely: the java developer, the server admin or (author of deployment descriptor) and the network admin responsible for url allocation.

All struts applications try to mock front-controller pattern. (A true front controller has no logic what so ever and just delegates, it is left to application designers to come up with the delegators/handlers. In struts 1.xx this is achieved only by using a 'request processor', which is not the default. The delegation logic is held by front-controller in default case. The user can configure the delegation rules). The front-controller is called 'ActionServlet' and is part of struts library. In the above example all urls that match the regex *.do are mapped to this servlet. There are some initialization parameters given to action servlet, the most important of these is the 'config' parameter, we supply struts-config.xml(s) here. Multiple config.xmls are allowed and are comma separated. The config.xmls contain the rules to be followed for request delegation. These are used by ActionServlet.

When a request hits actionservlet, the servlet tries to map it to the appropriate action. Action is a specialised controller. ActionServlet also maps the request parameters to a bean, called as form-bean in struts lingo. By the time request reaches action class, the form-bean gets populated and acts as a data structure. Validation of parameters can be done in the Action class, but the most appropriate location would be form-bean, as per ObjectOriented model. We will see more of struts-config.xml in the next part

Last but not the least are tld definitions provided at the end. These have more to do with jsp tag-libs than struts framework. Think of them as helper classes.

Note


Struts 2 and Spring framework are ideologically more similar than struts 1. In the former, user is allowed to dictate the front-controller (dispatch servlet), user is not forced to extend framework classes. This amounts to greater freedom of design (loose coupling or framework agnostic design). However, how many times did we see an application design change radically?

Popular Posts

Labels

About Me

Well for a start, I dont' want to!. Yes I am reclusive, no I am not secretive; Candid? Yes; Aspergers? No :). My friends call me an enthusiast, my boss calls me purist, I call myself an explorer, to summarise; just an inquisitive child who didnt'learn to take things for granted. For the sake of living, I work as a S/W engineer. If you dont' know what it means, turn back right now.