Use Autowired in Custom Tags in Spring MVC Framework

On the Eclipse, create a Spring MVC project

Enter Project Information:

  • Name: LearnSpringMVCWithRealApps
  • Group: com.demo
  • Artifact: LearnSpringMVCWithRealApps
  • Description: Learn Spring MVC with Real Apps
  • Package: com.demo

Select the technologies and libraries to be used:

  • Web

Click Next button to show Site Information for project

Click Finish button to finish create Spring MVC project




<?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 https://maven.apache.org/xsd/maven-4.0.0.xsd">
	<modelVersion>4.0.0</modelVersion>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>2.1.10.RELEASE</version>
		<relativePath /> <!-- lookup parent from repository -->
	</parent>
	<groupId>com.demo</groupId>
	<artifactId>LearnSpringMVCWithRealApps</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<name>LearnSpringMVCWithRealApps</name>
	<description>Learn Spring MVC with Real Apps</description>

	<properties>
		<java.version>1.8</java.version>
	</properties>

	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>

		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-devtools</artifactId>
			<scope>runtime</scope>
			<optional>true</optional>
		</dependency>

		<dependency>
			<groupId>org.apache.tomcat.embed</groupId>
			<artifactId>tomcat-embed-jasper</artifactId>
			<scope>provided</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>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-test</artifactId>
			<scope>test</scope>
		</dependency>
	</dependencies>

	<build>
		<plugins>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>

</project>




spring.mvc.view.prefix = /WEB-INF/views/
spring.mvc.view.suffix = .jsp
spring.mvc.static-path-pattern=/resources/**

server.port=9596

Create new package, named com.demo.entities. In this package, create new java class named Product.java as below:

package com.demo.entities;

public class Product {

	private String id;
	private String name;
	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 double getPrice() {
		return price;
	}

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

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

	public Product() {
		super();
	}

}




Create new package named com.demo.repositories. In this package, create new interface named ProductRepository interface as below:

package com.demo.repositories;

import java.util.List;

import com.demo.entities.Product;

public interface ProductRepository {

	public Product find();

	public List<Product> findAll();

}

In com.demo.repositories package, create new java class named ProductRepositoryImpl.java implements methods from ProductRepository interface as below:

package com.demo.repositories;

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

import org.springframework.stereotype.Repository;

import com.demo.entities.Product;

@Repository("productRepository")
public class ProductRepositoryImpl implements ProductRepository {

	@Override
	public Product find() {
		return new Product("p01", "name 1", 4.5);
	}

	@Override
	public List<Product> findAll() {
		List<Product> products = new ArrayList<Product>();
		products.add(new Product("p01", "name 1", 4.5));
		products.add(new Product("p02", "name 2", 2));
		products.add(new Product("p03", "name 3", 3));
		return products;
	}

}

Create new package named com.demo.services. In this package, create new interface named ProductService.java as below:

package com.demo.services;

import java.util.List;

import com.demo.entities.Product;

public interface ProductService {

	public Product find();

	public List<Product> findAll();

}

In com.demo.services package, create new java class named ProductServiceImpl.java implements methods from ProductService interfaces as below:

package com.demo.services;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.demo.entities.Product;
import com.demo.repositories.ProductRepository;

@Repository("productService")
public class ProductServiceImpl implements ProductService {

	@Autowired
	private ProductRepository productRepository;

	@Override
	public Product find() {
		return productRepository.find();
	}

	@Override
	public List<Product> findAll() {
		return productRepository.findAll();
	}

}




Create new folder named tlds in src\main\webapp\WEB-INF folder. In this folder, create new TLD file named myTags.tld as below:

<taglib 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/web-jsptaglibrary_2_0.xsd"
	version="2.0">

	<tlib-version>1.0</tlib-version>
	<short-name>My Tags</short-name>
	<uri>mytags</uri>

	<tag>
		<name>tag1</name>
		<tag-class>com.demo.tags.Tag1</tag-class>
		<body-content>empty</body-content>
	</tag>

	<tag>
		<name>tag2</name>
		<tag-class>com.demo.tags.Tag2</tag-class>
		<body-content>empty</body-content>
	</tag>

</taglib>

Create new package named com.demo.tags. In this package, create new Tag Handlers as below:

In com.demo.tags package, create new Java class named Tag1.java as below:

package com.demo.tags;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspWriter;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.tags.RequestContextAwareTag;

import com.demo.services.ProductService;

public class Tag1 extends RequestContextAwareTag {

	@Autowired
	private ProductService productService;

	@Override
	protected int doStartTagInternal() throws Exception {
		if (productService == null) {
			WebApplicationContext webApplicationContext = getRequestContext().getWebApplicationContext();
			AutowireCapableBeanFactory autowireCapableBeanFactory = webApplicationContext.getAutowireCapableBeanFactory();
			autowireCapableBeanFactory.autowireBean(this);
		}
		return SKIP_BODY;
	}

	@Override
	public void doFinally() {
		JspWriter out = pageContext.getOut();
		try {
			String jspPage = "../tags/tag1.jsp";
			HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
			request.setAttribute("product", productService.find());
			request.getRequestDispatcher(jspPage);
			pageContext.include(jspPage);
		} catch (Exception e) {
			try {
				out.print(e.getMessage());
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		}
	}

}




In com.demo.tags package, create new Java class named Tag2.java as below:

package com.demo.tags;

import java.io.IOException;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspWriter;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.AutowireCapableBeanFactory;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.servlet.tags.RequestContextAwareTag;

import com.demo.services.ProductService;

public class Tag2 extends RequestContextAwareTag {

	@Autowired
	private ProductService productService;

	@Override
	protected int doStartTagInternal() throws Exception {
		if (productService == null) {
			WebApplicationContext webApplicationContext = getRequestContext().getWebApplicationContext();
			AutowireCapableBeanFactory autowireCapableBeanFactory = webApplicationContext.getAutowireCapableBeanFactory();
			autowireCapableBeanFactory.autowireBean(this);
		}
		return SKIP_BODY;
	}

	@Override
	public void doFinally() {
		JspWriter out = pageContext.getOut();
		try {
			String jspPage = "../tags/tag2.jsp";
			HttpServletRequest request = (HttpServletRequest) pageContext.getRequest();
			request.setAttribute("products", productService.findAll());
			request.getRequestDispatcher(jspPage);
			pageContext.include(jspPage);
		} catch (Exception e) {
			try {
				out.print(e.getMessage());
			} catch (IOException e1) {
				e1.printStackTrace();
			}
		}
	}

}

Create new folder named tags in src\main\webapp\WEB-INF\views folder. In this folder, new new JSP files as below:

Create new JSP file named tag1.jsp as below:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
    pageEncoding="ISO-8859-1" isELIgnored="false"%>
<h3>Tag 3</h3>
id: ${product.id}
<br>
name: ${product.name}
<br>
price: ${product.price}

Create new JSP file named tag2.jsp as below:

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1" isELIgnored="false"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<h3>Tag 4</h3>
<c:forEach var="product" items="${products }">
	id: ${product.id}
	<br>
	name: ${product.name}
	<br>
	price: ${product.price}
	<br>
	=========================
	<br>
</c:forEach>




Create new package named com.demo.controllers. In this package, create controllers as below:

Create new java class, named DemoController.java

package com.demo.controllers;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

@Controller
@RequestMapping(value = { "", "demo" })
public class DemoController {

	@RequestMapping(method = RequestMethod.GET)
	public String index() {
		return "demo/index";
	}

}

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




Create new folder named demo. Create new jsp file named index.jsp

<%@ page language="java" contentType="text/html; charset=ISO-8859-1"
	pageEncoding="ISO-8859-1" isELIgnored="false"%>
<%@ taglib prefix="mt" uri="mytags"%>
<!DOCTYPE html>
<html>
<head>
<meta charset="ISO-8859-1">
<title>Index</title>
</head>
<body>

	<mt:tag1 />
	<br>
	<mt:tag2 />

</body>
</html>

Select LearnSpringMVCWithRealAppsApplication.java file in com.demo package, right click and select Run As/Spring Boot App menu

Access index method in demo controller with following url: http://localhost:9596/demo

Output