Spring is widely used in companies. Whether it is Struts or Hibernate or other services like mail, jms, security or jax-ws, it is required to be used through Spring.
So, I am trying to develop a struts demo through Spring.
Even for integrating Struts1.1 with Spring, there are 3 methods. ( as mentioned in the famous book ‘Spring in Action’ by Craig Walls..p347 to 351).. The first method is easiest. In that case, I just extended my action class from Spring’s ActionSupport class.
The code snippet will be as follows.
( we must import
import org.springframework.context.
ApplicationContext;
import org.springframework.web.struts.
ActionSupport;
public class demoAction extends ActionSupport
{
public ActionForward execute
(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws Exception
{
ApplicationContext context=
getWebApplicationContext();
helper helper1 =
(helper) context.getBean(“helper1”);
String r = helper1.help();
request.setAttribute(“result”,r);
return
mapping.findForward(“success”);
}
// etc as usual.
So the only change will be this and all the other struts files will be same.
Ofcourse, we will have beans.xml where we define helper class and helper bean.
The mapping is done in beans.xml
as follows.( this is Spring file)
=================================
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean name="bean1"
class="demopack.hellobean">
</bean>
</beans>
================================
This helper class can be as simple as hellobean or jdbcquerybean or hibernatebean.
It makes little difference.
This is the first iteration.
I got correct result , whatever be the helperclass.
This is the simplest method.
================================
The objection may be that it ties our code tightly with Spring.
So, there is a second method known as Delegation method.
In this case, my action class is NOT derived from ActionSupport.
The code snippet for my action class is:
public class demoAction extends Action
{
public hellobean bean1;
public void setBean1
(hellobean b){bean1=b;}
public ActionForward execute(
ActionMapping mapping, ActionForm form, HttpServletRequest request, HttpServletResponse response)
throws IOException,ServletException
{
demoForm demoform =
( demoForm) form;
String s1 =
demoform.getName(); String r=bean1.sayhello( s1);
request.setAttribute
("result", r);
return (mapping.findForward("success"));
}
}
But we have to make an entry in struts-config file as follows:
-------------------------------
<form-bean name="demoForm" type="demopack.demoForm" />
</form-beans>
...
<action
path="/demo"
input="/demoInput.jsp"
name="demoForm"
type="org.springframework.web.
struts.DelegatingActionProxy"
scope="session"
validate="true" >
<forward name="success" path="/demoOutput.jsp" />
<forward name="failure" path="/demoInput.jsp" />
</action>
</action-mappings>
...
<plug-in
className =
"org.springframework.web.struts.
ContextLoaderPlugIn">
<set-property property="contextConfigLocation"
value = "/WEB-INF/beans.xml"/>
</plug-in>
</struts-config>
And then we have to map demoAction and our helper class in beans.xml file.
<bean name="bean1"
class="demopack.hellobean"/>
<bean name="/demo"
class="demopack.demoAction" >
<property name="bean1">
<ref bean="bean1"/>
</property>
</bean>
we should be careful when setting the name property of the bean which points to ‘demoAction’ class. The value of the name property should be same as the value of ‘path’ property of <action> tag.
The third method is
‘Request Delegation’ .
Spring provides DelegatingRequesProcessor for <controller> tag (in struts-config.xml)
It will be stated as
<controller processorClass = "org.springframework.web.struts.
DelegatingRequestProcessor"/>
when you are using request delegation method, you need not specify the type attribute in the <action> tag.
when a request received for “/demo”, DelegatingRequesProcessor will automatically refer to beans.xml file for the appropriate action.
Apart from this <controller> tag, every thing is same as delegate method
<action
path="/demo"
input="/demoInput.jsp"
name="demoForm"
scope="session"
validate="true" >
...
</action>
<controller processorClass=
"org.springframework.web.struts.
DelegatingRequestProcessor"/>
...
<plug-in
className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation"
value="/WEB-INF/beans.xml"/>
</plug-in>
================================
Next example is about integrating struts1.1 , spring1.2 and jdbc
I begin with demoInput.jsp. almost demoInput.jsp,
demoForm.java and demoOutput.jsp are very similar
to a usual struts application.
But, demoAction.java code has to be changed a bit from
our usual pattern and ofcourse, helper class (In our case
springhiberbean is the helper class)is DAO and it
is very simple.In this bean I have written code only for
displaying the records.
Apart from these things, we have to concentrate on xml
files also.
In addition to struts-config.xml
we have to provide spring application context xml file.
this spring application context(beans.xml file in ourcase) file is to be
accessed through
struts-config.xml
for clearity I have given the code for demoInput.jsp,
<%@ taglib uri="/WEB-INF/struts-html.tld" prefix="html" %>
<html>
<body bgcolor=green text=cyan>
<html:errors />
<html:form action="/demo"
name="demoForm"
type="demopack.demoForm">
type your name (only admin can view records)
<br>
<html:text property="name" /> name<br>
<html:submit />
</html:form>
</body>
</html>
In above code, I highlighted the ‘action’ attribute.
we all know that demoAction(Action) class is highly
tie up with servlet API. So, There will be some difficulties
in testing Action class.
To avoid these difficulties, spring introduced Dependency
Injection concept. and so It has to be mapped in spring application
context (beans.xml) file.
When mapping this demoAction class in struts-config file, we have to use this
action=’/demo’.
demoForm.java will be having setter getter method code as usual.
For brevity, I skipped the demoForm and demoOutput.jsp.
demoAction.java
package demopack;
import java.io.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.apache.struts.action.*;
public class demoAction extends Action
{
public springquerybean bean1;
public void setBean1(springquerybean b){bean1=b;}
public ActionForward execute(ActionMapping mapping,
ActionForm form,
HttpServletRequest request,
HttpServletResponse response)
throws IOException,ServletException
{
demoForm demoform = ( demoForm) form;
String s1 = demoform.getName();
System.out.println(s1);
//-----------------------------------------------------
if(s1.equals("admin"))
{
String r=bean1.getrecords();
System.out.println(r);
request.setAttribute("result", r);
return (mapping.findForward("success"));
}
else
{
return (mapping.findForward("failure"));
}
}
}
Apart from the highlighted lines, every thing is similar to usual code.
springquerybean object will be passed to setter function through beans.xml
file.
The following code is for springquerybean. It is DAO and the highlighted one is VO.
I have placed springquerybean and dsgetset in demopack. but it is not necessary.
The difference is If you placed it in package, you have to specify that in beans.xml file as
<bean name="bean1"
class="demopack.springquerybean">
otherwise you can simply say
<bean name="bean1"
class="springquerybean">
So, you can use any bean. It doesn’t matter in which package
it is placed. The only thing is that you have to specify the package
in <bean> tag.
springquerybean.java
package demopack;
import java.io.*;
import javax.sql.*;
import java.sql.*;
import java.util.*;
import org.springframework.beans.factory.*;
import org.springframework.beans.factory.xml.*;
import org.springframework.core.io.*;
import org.springframework.jdbc.core.*;
import org.springframework.jdbc.datasource.*;
import org.springframework.jdbc.object.*;
import org.springframework.jdbc.support.*;
public class springquerybean
{
dsgetset dbean1;
public void setDbean1(dsgetset b){dbean1 = b;}
public String getrecords()
{
String r="";
try
{
DataSource ds=dbean1.getDatasource();
java.util.List list1;
JdbcTemplate jt = new JdbcTemplate(ds);
list1=jt.queryForList("select *from table1");
Iterator i=list1.iterator();
while(i.hasNext())
{
Object ob = i.next();
r=r+ob.toString()+"\n";
}
} catch(Exception e1)
{ r=r+e1;}
return r;
}
}
Value Object
dsgetset.java
package demopack;
import org.springframework.jdbc.core.*;
import org.springframework.jdbc.datasource.*;
import org.springframework.jdbc.object.*;
import org.springframework.jdbc.support.*;
import javax.sql.*;
public class dsgetset
{
DataSource datasource;
public void setDatasource(DataSource ds)
{ datasource = ds; }
public DataSource getDatasource()
{ return datasource; }
}
We can reduce this code some more by adding the dsgetset content to
springquerybean code. For clarity I have divided the code as two classes.
beans.xml file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean name="bean1"
class="demopack.springquerybean">
<property name="dbean1">
<ref bean="dsbean1"/>
</property>
</bean>
<bean name="/demo"
class="demopack.demoAction" >
<property name="bean1">
<ref bean="bean1"/>
</property>
</bean>
<bean id="datasource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName">
<value>sun.jdbc.odbc.JdbcOdbcDriver</value>
</property>
<property name="url">
<value>jdbc:odbc:contacts</value>
</property>
<property name="username">
<value>root</value>
</property>
<property name="password">
<value></value>
</property>
</bean>
<bean id="dsbean1" class="demopack.dsgetset">
<property name="datasource"><ref bean="datasource"/></property>
</bean>
</beans>
Next important thing is referring beans.xml file through struts-config.xml
file. For that you need to to insert an additional tag <plug-in> in struts
configuration file.
<form-bean name="demoForm" type="demopack.demoForm" />
</form-beans>
<action
path="/demo"
input="/demoInput.jsp"
name="demoForm"
type="org.springframework.web.struts.DelegatingActionProxy"
scope="session"
validate="true" >
<forward name="success" path="/demoOutput.jsp" />
<forward name="failure" path="/demoInput.jsp" />
</action>
</action-mappings>
<plug-in
className="org.springframework.web.struts.ContextLoaderPlugIn">
<set-property property="contextConfigLocation"
value="/WEB-INF/beans.xml"/>
</plug-in>
</struts-config>