Archive

Archive for the ‘Struts’ Category

Other Notes from migration to Spring 3

April 4, 2011 Leave a comment

Read my previous blog to see why I got here…

Here are some other things I tripped over when moving the project to Spring 3.0

If your project gets the following exception ..

java.lang.ClassNotFoundException: org.springframework.web.struts.ContextLoaderPlugIn

.. you are probably using Struts 1.1 and not including the struts dependency from Spring.
Include this in your maven dependencies and you should be good to go.

<dependency>
  <groupid>org.springframework</groupid>
  <artifactid>spring-struts</artifactid>
  <version>3.0.0.RELEASE</version>
</dependency>

Struts 1.1 dependency was removed in Spring 3.0 but was reintroduced later in deprecated form. Read more about it here.

If your project get the following exception…

java.lang.ClassNotFoundException: org.springframework.web.context.ContextLoaderServlet

… you were using Spring 2.3 or lower according to this entry.

 

Use ContextLoaderListener instead of ContextLoaderServlet.

Remove the servlet entry from your web.xml for ContextLoaderServlet and add the following listener…

<listener>
  <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Advertisements

Dynamic Forms with Map-backed ActionForms in Struts 1

September 14, 2010 4 comments

A project that I work on uses Struts 1 and I came across a problem where I intended to create a page that could have any number of text fields (number of fields would be increased by a button click). The idea was to have a way to have name – value text input boxes whose content would be saved in a properties database table when the form was submitted. After some blind google searches I came across “Map-backed” and “List-backed” properties in struts. This write-up is a summary of using Map-backed properties to achieve that goal. This article does not show how to save the values in the database however… it just logs the values received on the server.

As a first step we will create a blank Struts application with maven. Look at this article to create a blank application.
The next step is to create a page that will have our dynamic form. Here is the page(dynamicTextEntry.jsp)..

<%@ taglib uri="http://struts.apache.org/tags-bean" prefix="bean" %>
<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html" %>
<%@ taglib uri="http://struts.apache.org/tags-logic" prefix="logic" %>

<html:html>
<head>
<script type="text/javascript">
	function add(){
		var element1 = document.createElement("input");
		var element2 = document.createElement("input");
		var elementCount = parseInt(document.getElementById("count").value);

		element1.setAttribute("type","text");
		element1.setAttribute("value","Enter Name");
		element1.setAttribute("name","value(name"+ elementCount +")");

		element2.setAttribute("type","text");
		element2.setAttribute("value","Enter Value");
		element2.setAttribute("name","value(value"+ elementCount +")");

		var spanBody = document.getElementById("textBoxes");
		spanBody.appendChild(element1);
		spanBody.appendChild(element2);
		var breakElement = document.createElement('br');
		spanBody.appendChild(breakElement);
		
		document.getElementById("count").value = elementCount + parseInt(1);
	}
</script>
<title>Dynamic Entry Form</title>
<html:base/>
</head>
<body bgcolor="white">

<html:form action="setDynamicTextEntry.do" >
<html:hidden property="count" styleId="count" value="0"/>
<input type="button" value="Add Field (+)" onclick="add()"/>
</br>
<span id="textBoxes"></span>

<html:submit property="submit"> Submit</html:submit>

</html:form>
</body>
</html:html>

We will create two actions in struts-config.xml as follows… the action class is shown later…

	<action
            path="/dynamicInputs"
            forward="/pages/dynamicTextEntry.jsp"/>
		
	<action
            path="/setDynamicTextEntry"
            type="com.wordpress.codesilo.controller.SetDynamicTextEntryAction"
            name="dyamicTextEntryForm"
            scope="request"
            validate="true"
            input="/pages/dynamicTextEntry.jsp">
            <forward name="success" path="/pages/success.jsp"/>
        </action>

We will also add form bean to struts-config.xml

<form-bean name="dyamicTextEntryForm" type="com.wordpress.codesilo.model.DyamicTextEntryForm"></form-bean>

The action class is as follows…

public class SetDynamicTextEntryAction extends Action {

	
	@Override
	public ActionForward execute(ActionMapping mapping, ActionForm form,
			HttpServletRequest request, HttpServletResponse response)
			throws Exception {
		
		DyamicTextEntryForm dynform = (DyamicTextEntryForm)form;
		Map dynformValues = dynform.getValues();
		int count = dynformValues.size()/2;
		
		System.out.println("Map Size: " + dynformValues.size());
		for(int i =0; i<count ; i++){
			String name = (String)dynformValues.get("name"+i);
			String value = (String)dynformValues.get("value"+i);
			System.out.println("Name:" + name + " Value:" + value);
		}
		return mapping.findForward("success");
	}
}

The form is as follows…

public class DyamicTextEntryForm extends ActionForm {

	private final Map values = new HashMap();
	private int count;
	
	public int getCount() {
		return count;
	}

	public void setCount(int count) {
		this.count = count;
	}

	public Map getValues(){
		return values;
	}
	
	public void setValue(String key, Object value){
		values.put(key, value);
	}
	
	public Object getValue(String key){
		return values.get(key);
	}
	
}

Add a success page that is forwarded to once the form is submitted and we are ready to try out the code.
The page looks as follows… (Every time to click the add button a new pair of text boxes are added)
When we add/change text in the boxes and click submit, the values entered in the text boxes are displayed in the console.


Explanation:
The javascript in the jsp adds text boxes to the existing dom in pairs. The elements added would look like the following when rendered in HTML

<input type="text" value="Enter Name" name="value(name0)">
<input type="text" value="Enter Value" name="value(value0)">

Every time the button is clicked the count increments and new text boxes are added. So, on the second click the following elements are added…

<input type="text" value="Enter Name" name="value(name1)">
<input type="text" value="Enter Value" name="value(value1)">

Once the form is submitted, the setValue(String key, Object value) on the form is called for each of these text boxes. The key will be the names we provide (name0, value0, name1, value1 etc) and the value is the value from the text boxes.

Rest is self explanatory. 🙂

References:
http://struts.apache.org/1.x/userGuide/building_controller.html
http://www.manning-sandbox.com/message.jspa?messageID=26953

Struts 1.3.5 Tiles – Basics

May 24, 2010 Leave a comment

Struts tiles provides us a templating system. The introduction below shows the basic reusability of the modules of a web page.
To start, we will build a basic struts project using a maven archetype. Read more of it here.
Add a new dependency to the pom file

 <dependency>
 <groupId>org.apache.struts</groupId>
 <artifactId>struts-tiles</artifactId>
 <version>1.3.5</version>
 </dependency>

In struts-config.xml of the project , add the following plugin

 <plug-in className="org.apache.struts.tiles.TilesPlugin" >
 <set-property property="definitions-config" value="/WEB-INF/tiles-defs.xml" />
 <set-property property="definitions-parser-validate" value="true" />
 <set-property property="moduleAware" value="true" />
 </plug-in>

What we will now do is remove the default welcome.jsp page that was created by maven and reroute the request to a page (layout.jsp) that we create using tiles.
The components of the page will be the following : header.jsp, footer.jsp,menu.jsp , body.jsp and need to be located in the pages folder.
These will look as follows:

header.jsp

<div id="header">
 This is header
</div>

footer.jsp

<div id="footer">
 This is footer
</div>

body.jsp

<div id="body">
 This is body
</div>

menu.jsp

<div id="menu">
 This is menu
</div>

layout.jsp

<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>
<%@ taglib uri="http://struts.apache.org/tags-tiles" prefix="tiles"%>

<html:html>
<head>

</head>

<body>
<table>
<tr valign='top'><td style="background-color:LightSlateGray "><tiles:insert attribute="menu"/></td>
<td><table>
<tr><td style="background-color:LightSkyBlue"><tiles:insert attribute="header"/></td></tr>
<tr><td style="background-color:LightSteelBlue "><tiles:insert attribute="body"/></td></tr>
<tr><td style="background-color:LightSkyBlue"><tiles:insert attribute="footer"/></td></tr>
</table>
</td>
</tr>
</table>
</body>
</html:html>

Uncomment the following from web.xml

<init-param>
<param-name>chainConfig</param-name>
<param-value>org/apache/struts/tiles/chain-config.xml</param-value>
</init-param>

Create a file tiles-defs.xml in the webapp folder of the project with the following content

<?xml version="1.0" encoding="ISO-8859-1" ?>

<!DOCTYPE tiles-definitions PUBLIC
"-//Apache Software Foundation//DTD Tiles Configuration 1.1//EN"
"http://jakarta.apache.org/struts/dtds/tiles-config_1_3.dtd">
<tiles-definitions>
<definition name="Tiles.welcome" path="/pages/layout.jsp">
<put name="header" value="/pages/header.jsp" />
<put name="menu" value="/pages/menu.jsp" />
<put name="body" value="/pages/body.jsp" />
<put name="footer" value="/pages/footer.jsp" />
</definition>
</tiles-definitions>

So, now we have a tile definition by the name Tiles.welcome and the path /pages/layout.jsp. The layout.jsp has tiles header, menu, body and footer whose content will be in the files defined in the tiles-defs.xml file.

The last thing is to go to struts-config.xml file and change the forward path of the Welcome action…
Change ..

<action
path="/Welcome"
forward="/pages/Welcome.jsp"/>

to..

<action
path="/Welcome"
forward="Tiles.welcome"/>

Build and deploy the project. Go to the following url http://localhost:8080/test-struts-tiles (Note : The project I created was test-struts-tiles)
You should see the following

Note:
If you do not uncomment the lines in web.xml for chainConfig, you will get the following exception…
javax.servlet.ServletException: java.lang.IllegalArgumentException: Path Tiles.welcome does not start with a “/” character
org.apache.struts.chain.ComposableRequestProcessor.process(ComposableRequestProcessor.java:283)
org.apache.struts.action.ActionServlet.process(ActionServlet.java:1858)

<%@ taglib uri="http://struts.apache.org/tags-html" prefix="html"%>
<%@ taglib uri="http://struts.apache.org/tags-tiles" prefix="tiles"%>

<html:html>
<head>

</head>

<body>
<table>
<tr valign='top'><td style="background-color:LightSlateGray "><tiles:insert attribute="menu"/></td>
<td><table>
<tr><td style="background-color:LightSkyBlue"><tiles:insert attribute="header"/></td></tr>
<tr><td style="background-color:LightSteelBlue "><tiles:insert attribute="body"/></td></tr>
<tr><td style="background-color:LightSkyBlue"><tiles:insert attribute="footer"/></td></tr>
</table>
</td>
</tr>
</table>
</body>
</html:html>