Struts2 Native Dependency Injection
Struts2 provides support for Dependency injection. You may use DI containers like “Spring” in your Struts2 application, or may use Native Dependency Injection available in Struts2 (XWork2) framework. It’s based on Google’s “guice” (both being made by same person).
In this sample application, I have made Two Action classes:
- AddProductAction To Add new product
- ListProductAction To List all products
Both actions are dependent on a “Business” class : ProductManager. Instead of creating instance of ProductManager in each action class, I have created its instance through “bean” element in “struts.xml”.
<bean class="com.mahendra.ProductManager" name="man" />
The ObjectFactory available in Struts2 will create instance of ProductManager using default constructor and is made available to all other components using name : “man”.
Every Action class needs to have property of type “ProductManager” along with annotation:
@Inject("man") private ProductManager manager; // This method is used for Injecting Object public void setManager(ProductManager manager) { this.manager = manager; }
Now, lets create an application.
Requirements:
- Java SDK 1.6 (or newer)
- Eclipse helios (or newer)
- Apache Tomcat 6.0 (or 7.0)
- Struts 2.1.x from apache
Steps to create application:
- Create new Dynamic Web Application.
- Copy all required JAR’s inside “web-inf/lib” folderJARS required:
commons-fileupload commons-io commons-lang freemarker javassist ognl jstl (For JSTL Core Tags) struts2-core xwork-core
- Modify your “web.xml” to have Struts2 dispatcher filter.
<filter> <filter-name>struts2</filter-name> <filter-class>org.apache.struts2.dispatcher.FilterDispatcher </filter-class> </filter> <filter-mapping> <filter-name>struts2</filter-name> <url-pattern>/*</url-pattern> </filter-mapping>
- Create new “struts.xml” in your source folder:
<!DOCTYPE struts PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 2.1//EN" "http://struts.apache.org/dtds/struts-2.1.dtd"> <struts><bean class="com.mahendra.ProductManager" name="man" /> <package name="p1" extends="struts-default" namespace=""> <action name="add" class="com.mahendra.AddProductAction"> <result type="redirectAction">list</result> </action> <action name="list" class="com.mahendra.ListProductAction"> <result>list.jsp</result> </action> </package> </struts>
- Create Model class : Product
package com.mahendra; public class Product { private String name; private String description; private double price; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getDescription() { return description; } public void setDescription(String description) { this.description = description; } public double getPrice() { return price; } public void setPrice(double price) { this.price = price; } public Product(String name, String description, double price) { super(); this.name = name; this.description = description; this.price = price; } public Product() { super(); } }
- Shared “Business” class :
ProductManagerpackage com.mahendra; import java.util.*; public class ProductManager { private List<Product> products; public ProductManager() { System.out.println("Creating new manager..."); products = new LinkedList<Product>(); System.out.println("Empty Product list generated"); } public void add(Product p) { products.add(p); } public Product search(String name) { Product p = null; for (int i = 0; i < products.size(); i++) { if (products.get(i).getName().equals(name)) { p = products.get(i); break; } }return p; } public void delete(String name) { Product p = search(name); if (p != null) { products.remove(p); } } public List<Product> getProducts() { return products; } public void setProducts(List<Product> products) { this.products = products; } }
- Create First Action class to add new product: AddProductAction
package com.mahendra; import com.opensymphony.xwork2.ActionSupport; import com.opensymphony.xwork2.inject.Inject; public class AddProductAction extendsActionSupport { @Inject("man") private ProductManager manager; private Product product; public String execute() { manager.add(product); return SUCCESS; } public ProductManager getManager() { return manager; } // This method is used for Injecting Object public void setManager(ProductManager manager) { this.manager = manager; } public Product getProduct() { return product; } public void setProduct(Product product) { this.product = product; } }
- Create another action class to List all products: ListProductAction
import java.util.List; import com.opensymphony.xwork2.inject.Inject; public class ListProductAction { @Inject("man")// requires setter private ProductManager manager; private List<Product> productList; public String execute() { setProductList(manager.getProducts()); return "success"; } public ProductManager getManager() { return manager; } public void setManager(ProductManager manager) { this.manager = manager; } public List<Product> getProductList() { return productList; } public void setProductList(List<Product> productList) { this.productList = productList; } }
- Create new JSP page “index.jsp” and add following line to load “list” action.
<% response.sendRedirect("list.action"); %>
- Create new JSP page “list.jsp” and add following lines to render form and list.
<%@ taglib uri= "/struts-tags" prefix= "s"%> <html> <head> <meta http-equiv= "Content-Type" content= "text/html;charset=ISO-8859-1" > <title>Struts2 Dependency Demo</title> </head> <body> <s:form action="add" method="post" > <s:textfield name= "product.name" label= "Name of product" /> <s:textfield name= "product.description" label= "Description"/> <s:textfield name= "product.price" label= "Product Price" /> <s:submit value= "Save" /> </s:form> <h2>Available Products</h2> <table> <tr> <td>Product Name</td> <td>Description</td> <td>Price</td> </tr> <s:iterator value= "productList" var= "p" > <tr> <td>${p.name }</td> <td>${p.description }</td> <td>${p.price }</td> </tr> </s:iterator> </table> </body> </html>