Thursday 17 May 2012

Struts 2.3.3 integration with Spring 3.0.5 using Struts annotation

An example application to integrate Struts and Spring using the struts annotation. The application is very simple, just shown the way to do the confuguration and hence not implemented variuos features given by the two framework.

First we will do the configuration in the Deployment discriptor to use Struts FilterDispatcher and the spring WebApplicationContext. Below is the web.xml

------------------------------------------------------------------------------------
web.xml
------------------------------------------------------------------------------------





<?xml version="1.0" encoding="UTF-8"?>

<web-app id="starter" 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">
<display-name>Struts 2 - Maven Archetype - Starter</display-name>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath*:applicationContext*.xml</param-value>
</context-param>
<!-- Filters -->
<filter>
        <filter-name>action2-cleanup</filter-name>
        <filter-class>org.apache.struts2.dispatcher.ActionContextCleanUp</filter-class>
    </filter>
    <filter>
        <filter-name>action2</filter-name>
        <filter-class>org.apache.struts2.dispatcher.FilterDispatcher</filter-class>
    </filter>
<filter-mapping>
        <filter-name>action2-cleanup</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <filter-mapping>
        <filter-name>action2</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
<!-- Listeners -->
<listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
    </listener>
    
    
    <!-- Servlets -->
    <servlet>
    <servlet-name>jspSupportServlet</servlet-name>
    <servlet-class>org.apache.struts2.views.JspSupportServlet</servlet-class>
    <load-on-startup>5</load-on-startup>
    </servlet>
    
    
    <!-- Welcome file lists -->
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
        <welcome-file>default.jsp</welcome-file>
        <welcome-file>index.html</welcome-file>
    </welcome-file-list>

</web-app>

------------------------------------------------------------------------------------
now we will define the struts.xml for the basic configuration. This can be moved as per your requirment.
------------------------------------------------------------------------------------
struts.xml
------------------------------------------------------------------------------------





<!DOCTYPE struts PUBLIC
    "-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
    "http://struts.apache.org/dtds/struts-2.3.dtd">

<struts>
<constant name="struts.enable.DynamicMethodInvocation" value="false" />
<constant name="struts.devMode" value="false" />
<constant name="struts.convention.result.path" value="/pages" />
<constant name="struts.convention.action.packages" value="com.lnt.struts" />

<constant name="struts.objectFactory.spring.autoWire" value="auto" />
<package name="showcase" extends="struts-default,json-default"
namespace="/">
</package>
</struts>

------------------------------------------------------------------------------------
Now we will configure the spring webapplicationcontext so that we can integrate the spring with the struts.xml
------------------------------------------------------------------------------------
applicationContext.xml
------------------------------------------------------------------------------------






<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC 
"-//SPRING//DTD BEAN//EN" 
"http://www.springframework.org/dtd/spring-beans.dtd">

<beans default-autowire="autodetect">
<bean id="helloworld" class="com.lnt.struts.Testing" singleton="false">
</bean>
</beans>

------------------------------------------------------------------------------------

Now we will configure the struts mapping using the annotation in the class file. In the below java class we have annotated the method. The annotation "Action" has been used which tells the application that  for which url mapping which method or class has to be executed . In the below class we have defined the Action value as "helloworld", so when the url "/helloworld.action" will be hit the application knows which method it has to execute. We have also defined few more attributes. I mean results, which tells the application once it has executed the class as per the definition which view it has to redirect the control. The last configuration "className" is too important in the StrutsSpring application, As this attribute tells the application to look into the applicationContext of the spring for the particular bean definition defined.

Please note as our application is started the url "/helloworld.action" will be hit, so as per the configuration we have done the control will be coming to the HelloWorldAction.java. Once the control comes here the other configuration plays their part. The configuration "className" done above the method hello() tells the application to look for the name helloworld in the applicationcontext.xml.(the attribute "className" need not be same as url. you can give the same name you will define in the applicationContext.xml). Once the bean definition is seen the control moves to the class defined as per the applicationContext.xml. In our application the control moves to the Testing.java and executes the method hello(). This is because we have defined the configuration above the hello() method in the HelloWorldAction.java.(The controller takes the name of the method above which the configuration is defined and search and execute the same name method in the class defined by the spring bean).

Now if you dont want your spring configuration to overwrite the method defined by the struts, you just hace to remove the configuration "className". In that case the application will execute the method above which the mapping configuration has been defined. In our application that would be hello() method from the HelloWorldAction.java.
------------------------------------------------------------------------------------
HelloWorldAction .java
------------------------------------------------------------------------------------
package com.lnt.struts;

import org.apache.struts2.convention.annotation.Action;
import org.apache.struts2.convention.annotation.ParentPackage;
import org.apache.struts2.convention.annotation.Result;

import com.opensymphony.xwork2.ActionSupport;

@ParentPackage(value = "showcase")

public class HelloWorldAction extends ActionSupport {

@Action(value="helloworld",results={@Result(location="hello.jsp",name="success"),@Result(location="input.jsp",name="input"),@Result(location="error.jsp",name="error")},className="helloworld")
public String hello(){
System.out.println("inside Helloworld hello");
return "error";
}
  
    public String execute() throws Exception {
        System.out.println("inside execute method");
     return SUCCESS;
    }
}

------------------------------------------------------------------------------------
Testing.java
------------------------------------------------------------------------------------
package com.lnt.struts;
public class Testing {
 public String hello(){
  System.out.println("inside Testing hello");
  return "error";
 }

  public String execute() throws Exception {
         System.out.println("inside Testing execute method");
      return "success";
     }
}

 ------------------------------------------------------------------------------------

Now you may be wondering why other methods are been defined if its not used any where...... It is just to let you know how to define the same configuration for a class. For example

@ParentPackage(value = "showcase")
@Action(value="helloworld",results={@Result(location="hello.jsp",name="success"),@Result(location="input.jsp",name="input"),@Result(location="error.jsp",name="error")},className="helloworld")
public class HelloWorldAction extends ActionSupport {
// same code as above except the configuration above the method.
}

When you are defining configuration for the class the same configuration you need to put above the class declaration. Now the application will act the same way it has done for the method but instead of executing the hello() method defined in the class it will execute the execute() method of the class. This is because we have exetended our class to ActionSupport. Now as per the configuration of the "className", the application will decide which method to execute from which class the same way it does for the method configuration.
------------------------------------------------------------------------------------
error.jsp
------------------------------------------------------------------------------------




<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
error
</body>
</html>


------------------------------------------------------------------------------------
input.jsp
------------------------------------------------------------------------------------




<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
input
</body>
</html>

------------------------------------------------------------------------------------
hello.jsp
------------------------------------------------------------------------------------
<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Insert title here</title>
</head>
<body>
Hello
</body>
</html>
------------------------------------------------------------------------------------
index.jsp
------------------------------------------------------------------------------------




<% response.sendRedirect("helloworld.action"); %>


the index.jsp can be avoided by configuring the welcome tag in the web.xml to directly pointing helloworld.action url.
------------------------------------------------------------------------------------
Project Sturcture
------------------------------------------------------------------------------------

------------------------------------------------------------------------------------
library required
------------------------------------------------------------------------------------
this jar list is for various other needs. Whole jars may not be needed for this application
  1. antlr-2.7.6.jar
  2. aopalliance-1.0.jar
  3. asm-3.3.jar
  4. asm-commons-3.3.jar
  5. asm-tree-3.3.jar
  6. c3p0-0.9.1.jar
  7. commons-collections-3.1.jar
  8. commons-fileupload-1.1.1.jar
  9. commons-io-2.0.1.jar
  10. commons-lang3-3.1.jar
  11. commons-logging-1.0.4.jar
  12. dom4j-1.6.1.jar
  13. dwr-1.1-beta-3.jar
  14. freemarker-2.3.19.jar
  15. hibernate-c3p0-3.6.3.Final.jar
  16. hibernate-commons-annotations-3.2.0.Final.jar
  17. hibernate-core-3.6.3.Final.jar
  18. hibernate-jpa-2.0-api-1.0.0.Final.jar
  19. javassist-3.11.0.GA.jar
  20. jta-1.1.jar
  21. log4j-1.2.16.jar
  22. mysql-connector-java-5.1.9.jar
  23. ognl-3.0.5.jar
  24. sitemesh-2.4.2.jar
  25. slf4j-api-1.6.4.jar
  26. slf4j-jcl-1.6.4.jar
  27. slf4j-log4j12-1.6.4.jar
  28. spring-2.5.6.jar
  29. spring-aop-3.0.5.RELEASE.jar
  30. spring-asm-3.0.5.RELEASE.jar
  31. spring-beans-3.0.5.RELEASE.jar
  32. spring-context-3.0.5.RELEASE.jar
  33. spring-core-3.0.5.RELEASE.jar
  34. spring-expression-3.0.5.RELEASE.jar
  35. spring-web-3.0.5.RELEASE.jar
  36. struts2-config-browser-plugin-2.3.3.jar
  37. struts2-convention-plugin-2.3.3.jar
  38. struts2-core-2.3.3.jar
  39. struts2-sitemesh-plugin-2.3.3.jar
  40. struts2-spring-plugin-2.3.3.jar
  41. xwork-core-2.3.3.jar
------------------------------------------------------------------------------------
pom.xml configuration for the above project:
------------------------------------------------------------------------------------
this pom.xml is configured to use Struts 2.3.3 , Spring 3.0.5 , Hibernate 3.6.3 and mysql 5.1





<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.lnt</groupId>
<artifactId>struts</artifactId>
<name>StrutsSpringproject</name>
<packaging>war</packaging>
<version>1.0.0-BUILD-SNAPSHOT</version>
<properties>
<struts2.version>2.3.3</struts2.version>
</properties>

<dependencies>
<!-- Junit -->
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>

<!-- Struts 2 -->
<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-core</artifactId>
<version>${struts2.version}</version>
</dependency>

<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-sitemesh-plugin</artifactId>
<version>${struts2.version}</version>
</dependency>

<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-spring-plugin</artifactId>
<version>${struts2.version}</version>
</dependency>

<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-config-browser-plugin</artifactId>
<version>${struts2.version}</version>
</dependency>

<dependency>
<groupId>org.apache.struts</groupId>
<artifactId>struts2-convention-plugin</artifactId>
<version>${struts2.version}</version>
</dependency>
<!-- Servlet & Jsp -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
<scope>provided</scope>
</dependency>

<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jsp-api</artifactId>
<version>2.0</version>
<scope>provided</scope>
</dependency>

<!-- Jakarta Commons -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.1.1</version>
</dependency>

<!-- Dwr -->
<dependency>
<groupId>uk.ltd.getahead</groupId>
<artifactId>dwr</artifactId>
<version>1.1-beta-3</version>
</dependency>

<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-core</artifactId>
<version>3.6.3.Final</version>
</dependency>

<!-- Hibernate c3p0 connection pool -->
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-c3p0</artifactId>
<version>3.6.3.Final</version>
</dependency>


<!-- log4j dependency -->
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>1.6.4</version>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-jcl</artifactId>
<version>1.6.4</version>
</dependency>

<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
<version>1.6.4</version>
</dependency>

<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
<version>2.5.6</version>
</dependency>

<!-- MySQL database driver -->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>5.1.9</version>
</dependency>

<!-- Strutsjquery plugin dependency start -->
<!-- <dependency> <groupId>com.jgeppert.struts2.jquery</groupId> <artifactId>struts2-jquery-plugin</artifactId> 
<version>3.3.1</version> </dependency> <dependency> <groupId>com.jgeppert.struts2.jquery</groupId> 
<artifactId>struts2-jquery-grid-plugin</artifactId> <version>3.3.1</version> 
</dependency> <dependency> <groupId>com.jgeppert.struts2.jquery</groupId> 
<artifactId>struts2-jquery-richtext-plugin</artifactId> <version>3.3.1</version> 
</dependency> <dependency> <groupId>com.jgeppert.struts2.jquery</groupId> 
<artifactId>struts2-jquery-tree-plugin</artifactId> <version>3.3.1</version> 
</dependency> <dependency> <groupId>com.jgeppert.struts2.jquery</groupId> 
<artifactId>struts2-jquery-mobile-plugin</artifactId> <version>3.3.1</version> 
</dependency> -->

</dependencies>
<build>
<plugins>
<plugin>
<artifactId>maven-eclipse-plugin</artifactId>
<version>2.9</version>
<configuration>
<additionalProjectnatures>
<projectnature>org.springframework.ide.eclipse.core.springnature</projectnature>
</additionalProjectnatures>
<additionalBuildcommands>
<buildcommand>org.springframework.ide.eclipse.core.springbuilder</buildcommand>
</additionalBuildcommands>
<downloadSources>true</downloadSources>
<downloadJavadocs>true</downloadJavadocs>
</configuration>
</plugin>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>2.3.2</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<compilerArgument>-Xlint:all</compilerArgument>
<showWarnings>true</showWarnings>
<showDeprecation>true</showDeprecation>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>org.test.int1.Main</mainClass>
</configuration>
</plugin>
</plugins>
</build>
</project>
------------------------------------------------------------------------------------
project structure as a maven project
------------------------------------------------------------------------------------




No comments:

Post a Comment