Build Shopping Cart with Session in Struts 2

On the Eclipse, create a Maven project

Click Next button and select Workspace location for project

Click Next button and select maven-archetype-webapp

Click Next button and enter Project Information:

  • GroupId: LearnStrutsFrameworkWithRealApps
  • Artifact Id: LearnStrutsFrameworkWithRealApps
  • Package: com.demo

Click Finish button to finish create Maven project




Select current project, Right click and select Properties menu. In Properties dialog, select Targeted Runtime in left side after select Tomcat server from server list in right side

Click Ok button to finish

Select current project, Right click and select Build Path\Configure Build Path menu Select JRE System Library in Libraries tab:

Click Edit button and select JRE System Library you need use as below:

Click Finish button to finish




Open pom.xml file and add configurations for Struts 2 as below:

<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>LearnStrutsFrameworkWithRealApps</groupId>
	<artifactId>LearnStrutsFrameworkWithRealApps</artifactId>
	<packaging>war</packaging>
	<version>0.0.1-SNAPSHOT</version>
	<name>LearnStrutsFrameworkWithRealApps Maven Webapp</name>
	<url>http://maven.apache.org</url>
	<dependencies>

		<dependency>
			<groupId>junit</groupId>
			<artifactId>junit</artifactId>
			<version>3.8.1</version>
			<scope>test</scope>
		</dependency>

		<dependency>
			<groupId>javax.servlet.jsp.jstl</groupId>
			<artifactId>javax.servlet.jsp.jstl-api</artifactId>
			<version>1.2.1</version>
		</dependency>

		<dependency>
			<groupId>taglibs</groupId>
			<artifactId>standard</artifactId>
			<version>1.1.2</version>
		</dependency>

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

		<!-- Struts 2 Framework -->

		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-core</artifactId>
			<version>2.5.20</version>
		</dependency>

		<dependency>
			<groupId>org.apache.struts</groupId>
			<artifactId>struts2-convention-plugin</artifactId>
			<version>2.5.20</version>
		</dependency>

	</dependencies>

	<build>
		<finalName>LearnStrutsFrameworkWithRealApps</finalName>
	</build>

</project>




Open web.xml file in src\main\webapp\WEB-INF folder and add configurations for Struts 2 as below:

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
		 http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd"
	version="3.1">

	<display-name>Learn Struts 2 Framework with Real Apps</display-name>

	<filter>
		<filter-name>struts2</filter-name>
		<filter-class>org.apache.struts2.dispatcher.filter.StrutsPrepareAndExecuteFilter</filter-class>
		<init-param>
			<param-name>struts.devMode</param-name>
			<param-value>true</param-value>
		</init-param>
		<init-param>
			<param-name>struts.action.extension</param-name>
			<param-value>html</param-value>
		</init-param>
	</filter>

	<filter-mapping>
		<filter-name>struts2</filter-name>
		<url-pattern>/*</url-pattern>
		<dispatcher>REQUEST</dispatcher>
		<dispatcher>FORWARD</dispatcher>
		<dispatcher>INCLUDE</dispatcher>
	</filter-mapping>

	<welcome-file-list>
		<welcome-file>index.jsp</welcome-file>
	</welcome-file-list>

</web-app>

Create new folder named assets in src\main\webapp folder. In assets folder, create new folder named images and copy images need use in project to images folder.




Create new package named entities. In this package, create new entities as below

In entities package, create new java class named Product.java as below:

package entities;

public class Product {

	private String id;
	private String name;
	private String photo;
	private double price;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String getPhoto() {
		return photo;
	}

	public void setPhoto(String photo) {
		this.photo = photo;
	}

	public double getPrice() {
		return price;
	}

	public void setPrice(double price) {
		this.price = price;
	}

	public Product() {
	}

	public Product(String id, String name, String photo, double price) {
		this.id = id;
		this.name = name;
		this.photo = photo;
		this.price = price;
	}

}

In entities package, create new java class named Item.java as below:

package entities;

public class Item {

	private Product product;
	private int quantity;

	public Product getProduct() {
		return product;
	}

	public void setProduct(Product product) {
		this.product = product;
	}

	public int getQuantity() {
		return quantity;
	}

	public void setQuantity(int quantity) {
		this.quantity = quantity;
	}

	public Item() {
	}

	public Item(Product product, int quantity) {
		this.product = product;
		this.quantity = quantity;
	}

}




Create new package named models. In this package, create new models as below:

In models package, create new java class named ProductModel.java as below:

package models;

import java.util.ArrayList;
import java.util.List;

import entities.Product;

public class ProductModel {

	private List<Product> products;

	public ProductModel() {
		this.products = new ArrayList<Product>();
		this.products.add(new Product("p01", "name 1", "thumb1.gif", 20));
		this.products.add(new Product("p02", "name 2", "thumb2.gif", 21));
		this.products.add(new Product("p03", "name 3", "thumb3.gif", 22));
	}

	public List<Product> findAll() {
		return this.products;
	}

	public Product find(String id) {
		for (Product product : this.products) {
			if (product.getId().equalsIgnoreCase(id)) {
				return product;
			}
		}
		return null;
	}

}

Create new package named controllers.action in src/main/java folder. The action class in Struts 2 must be put in a package named action. In this package, create new actions as below:

In controllers.action package, create new java class named ProductAction.java as below:

package controllers.action;

import java.util.List;

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

import com.opensymphony.xwork2.ActionSupport;

import entities.Product;
import models.ProductModel;

@Namespace("/product")
public class ProductAction extends ActionSupport {

	private static final long serialVersionUID = 1L;

	private List<Product> products;

	public List<Product> getProducts() {
		return products;
	}

	public void setProducts(List<Product> products) {
		this.products = products;
	}

	@Action(value = "index", results = {
		@Result(name = SUCCESS, location = "/WEB-INF/views/product/index.jsp")
	})
	public String index() {
		ProductModel productModel = new ProductModel();
		this.products = productModel.findAll();
		return SUCCESS;
	}

}




In controllers.action package, create new java class named CartAction.java as below:

package controllers.action;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

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

import com.opensymphony.xwork2.ActionContext;
import com.opensymphony.xwork2.ActionSupport;

import entities.Item;
import models.ProductModel;

@Namespace("/cart")
public class CartAction extends ActionSupport {

	private static final long serialVersionUID = 1L;

	private String id;

	public String getId() {
		return id;
	}

	public void setId(String id) {
		this.id = id;
	}

	@Action(value = "index", results = {
		@Result(name = SUCCESS, location = "/WEB-INF/views/cart/index.jsp")
	})
	public String index() {
		return SUCCESS;
	}

	@Action(value = "buy", results = {
		@Result(name = SUCCESS, type = "redirectAction", params = { "namespace", "/cart", "actionName", "index" })
	})
	public String buy() {
		Map<String, Object> session = ActionContext.getContext().getSession();
		ProductModel productModel = new ProductModel();
		if (session.get("cart") == null) {
			List<Item> cart = new ArrayList<Item>();
			cart.add(new Item(productModel.find(id), 1));
			session.put("cart", cart);
		} else {
			List<Item> cart = (List<Item>) session.get("cart");
			int index = this.exists(id, cart);
			if (index == -1) {
				cart.add(new Item(productModel.find(id), 1));
			} else {
				int quantity = cart.get(index).getQuantity() + 1;
				cart.get(index).setQuantity(quantity);
			}
			session.put("cart", cart);
		}
		return SUCCESS;
	}

	@Action(value = "remove", results = {
		@Result(name = SUCCESS, type = "redirectAction", params = { "namespace", "/cart", "actionName", "index" })
	})
	public String remove() {
		Map<String, Object> session = ActionContext.getContext().getSession();
		List<Item> cart = (List<Item>) session.get("cart");
		int index = this.exists(id, cart);
		cart.remove(index);
		session.put("cart", cart);
		return SUCCESS;
	}

	private int exists(String id, List<Item> cart) {
		for (int i = 0; i < cart.size(); i++) {
			if (cart.get(i).getProduct().getId().equalsIgnoreCase(id)) {
				return i;
			}
		}
		return -1;
	}

}




Create new folder named views in src\main\webapp\WEB-INF folder. In views folder, create new views as below:

Create new folder named product. Create new jsp file named index.jsp as below:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1" isELIgnored="false"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Learn Struts 2 with Real Apps</title>
</head>
<body>

	<h3>Products Page</h3>
	<table cellpadding="2" cellspacing="2" border="1">
		<tr>
			<th>Id</th>
			<th>Name</th>
			<th>Photo</th>
			<th>Price</th>
			<th>Buy</th>
		</tr>
		<c:forEach var="product" items="${products }">
			<tr>
				<td>${product.id }</td>
				<td>${product.name }</td>
				<td>
					<img src="${pageContext.request.contextPath }/assets/images/${product.photo }" width="50">
				</td>
				<td>${product.price }</td>
				<td align="center">
					<s:url var="url_buy" namespace="/cart" action="buy">
						<s:param name="id">${product.id}</s:param>
					</s:url>
					<s:a href="%{url_buy}">Buy Now</s:a>
				</td>
			</tr>
		</c:forEach>
	</table>

</body>
</html>

Create new folder named cart. Create new jsp file named index.jsp as below:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1" isELIgnored="false"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
<title>Learn Struts 2 with Real Apps</title>
</head>
<body>

	<h3>Cart Page</h3>
	<table cellpadding="2" cellspacing="2" border="1">
		<tr>
			<th>Option</th>
			<th>Id</th>
			<th>Name</th>
			<th>Photo</th>
			<th>Price</th>
			<th>Quantity</th>
			<th>Sub Total</th>
		</tr>
		<c:set var="total" value="0"></c:set>
		<c:forEach var="item" items="${sessionScope.cart }">
			<c:set var="total" value="${total + item.product.price * item.quantity }"></c:set>
			<tr>
				<td align="center">
					<s:url var="url_remove" namespace="/cart" action="remove">
						<s:param name="id">${item.product.id }</s:param>
					</s:url>
					<s:a href="%{url_remove}" onclick="return confirm('Are you sure?')">Remove</s:a>
				</td>
				<td>${item.product.id }</td>
				<td>${item.product.name }</td>
				<td><img src="${pageContext.request.contextPath }/assets/images/${item.product.photo }"
					width="50"></td>
				<td>${item.product.price }</td>
				<td>${item.quantity }</td>
				<td>${item.product.price * item.quantity }</td>
			</tr>
		</c:forEach>
		<tr>
			<td colspan="6" align="right">Sum</td>
			<td>${total }</td>
		</tr>
	</table>
	<br>
	<s:a namespace="/product" action="index">Continue Shopping</s:a>

</body>
</html>




Create new jsp file named index.jsp in src\main\webapp folder as below:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1" pageEncoding="ISO-8859-1"%>
<jsp:forward page="product/index.html"></jsp:forward>




Select project, right click and select Run on Server menu

Access index method in product action with following url:

http://localhost:8080/LearnStrutsFrameworkWithRealApps/product/index.html

Output

Click Buy Now link from product page to buy a product and show it in cart page

Output

Click Remove link from cart page to remove product inside cart