Java Servlet Weld
last modified July 13, 2020
Java Servlet Weld tutorial shows how to use dependency injection in a Java Servlet with Weld. We use Weld with Tomcat web server.
Dependency injection
Dependency injection (DI) is a technique where one object supplies the dependencies of another object. In case of Java applications, it is a specific library that injects dependencies into the classes. The major benefit of DI is loose coupling and ease of use. DI makes classes more cohesive because they have fewer responsibilities.
Java EE standardized dependency injection by introducing the Context and Dependency Injection (CDI) specification. It is standard for dependency injection and contextual lifecycle management.
@Inject annotation
The @Inject annotation is used to inject a dependency into a Java class.
The dependency that is to be injected can be optionally decorated with @ManagedBean
annotation.
Weld
Weld is the reference implementation of CDI for the Java EE Platform. Weld is integrated into many Java EE application servers such as WildFly, JBoss, GlassFish, and others. Weld can also be used in plain servlet containers (Tomcat, Jetty) or Java SE.
Java Servlet Weld example
In the following web application, we create a servlet that returns a list of city objects in an HTML file. In the application, we use dependency injection with the help of the Weld library.
$ tree
.
├── nb-configuration.xml
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── zetcode
│ │ ├── bean
│ │ │ └── City.java
│ │ ├── dao
│ │ │ ├── CityDao.java
│ │ │ └── ICityDao.java
│ │ ├── service
│ │ │ ├── CityService.java
│ │ │ └── ICityService.java
│ │ └── web
│ │ └── GetCities.java
│ └── webapp
│ ├── index.html
│ ├── listCities.jsp
│ ├── META-INF
│ │ └── context.xml
│ └── WEB-INF
│ └── beans.xml
└── test
└── java
This is the project structure.
<?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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.zetcode</groupId>
<artifactId>JavaServletWeld</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>JavaServletWeld</name>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
</properties>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>javax.servlet-api</artifactId>
<version>4.0.0</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>1.2</version>
</dependency>
<dependency>
<groupId>org.jboss.weld.servlet</groupId>
<artifactId>weld-servlet-shaded</artifactId>
<version>3.0.2.Final</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-war-plugin</artifactId>
<version>3.2.0</version>
<configuration>
<failOnMissingWebXml>false</failOnMissingWebXml>
</configuration>
</plugin>
</plugins>
</build>
</project>
This is the Maven POM file. The javax.servlet-api artifact is
for servlets. The weld-servlet-shaded dependency enables Weld to
be run in a Servlet container. The jstl adds the JSTL library to
the project. JSTL includes a set of useful tags for JSP applications.
The maven-war-plugin is responsible for collecting all artifact dependencies,
classes and resources of the web application and packaging them into a web application archive (WAR).
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/JavaServletWeld">
<Resource name="BeanManager"
auth="Container"
type="javax.enterprise.inject.spi.BeanManager"
factory="org.jboss.weld.resources.ManagerObjectFactory" />
</Context>
In the Tomcat context.xml file, we define the context path
and register Weld's BeanManager factory.
package com.zetcode.bean;
import java.util.Objects;
public class City {
private Long id;
private String name;
private int population;
public City(Long id, String name, int population) {
this.id = id;
this.name = name;
this.population = population;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPopulation() {
return population;
}
public void setPopulation(int population) {
this.population = population;
}
@Override
public int hashCode() {
int hash = 3;
hash = 97 * hash + Objects.hashCode(this.id);
hash = 97 * hash + Objects.hashCode(this.name);
hash = 97 * hash + this.population;
return hash;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final City other = (City) obj;
if (this.population != other.population) {
return false;
}
if (!Objects.equals(this.name, other.name)) {
return false;
}
return Objects.equals(this.id, other.id);
}
}
The City bean holds data of a city object. It
has three attributes: id, name, and
population.
<?xml version="1.0"?>
<beans 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/beans_1_1.xsd"
version="1.1" bean-discovery-mode="all">
</beans>
In the WEB-INF directory, we have an empty beans.xml
file. It is a deployment descriptor for CDI. It can be used for configuring interceptors,
decorators, and other things. Even if we do no configurations, we need to add
an empty beans.xml for registering CDI.
package com.zetcode.service;
import com.zetcode.bean.City;
import java.util.List;
public interface ICityService {
public List<City> getCities();
}
ICityService contains the getCities contract method.
package com.zetcode.service;
import com.zetcode.bean.City;
import com.zetcode.dao.ICityDao;
import java.util.List;
import javax.annotation.ManagedBean;
import javax.inject.Inject;
@ManagedBean
public class CityService implements ICityService {
@Inject
private ICityDao cityDao;
@Override
public List<City> getCities() {
return cityDao.findAll();
}
}
CityService contains the implementation of the ICityService
interface. The service class calls the method of the DAO object, which is an intermediary
layer to the database.
@ManagedBean
public class CityService implements ICityService {
@ManagedBean is an optional annotation which indicates that the
CityService is going to be managed by Weld.
@Inject private ICityDao cityDao;
With the @Inject annotation, we inject the CityDao into
the cityDao attribute.
package com.zetcode.dao;
import com.zetcode.bean.City;
import java.util.List;
public interface ICityDao {
public List<City> findAll();
}
Here we have the DAO findAll contract method.
package com.zetcode.dao;
import com.zetcode.bean.City;
import java.util.ArrayList;
import java.util.List;
import javax.annotation.ManagedBean;
@ManagedBean
public class CityDao implements ICityDao {
@Override
public List<City> findAll() {
List<City> cities = new ArrayList<>();
cities.add(new City(1L, "Bratislava", 432000));
cities.add(new City(2L, "Budapest", 1759000));
cities.add(new City(3L, "Prague", 1280000));
cities.add(new City(4L, "Warsaw", 1748000));
cities.add(new City(5L, "Los Angeles", 3971000));
cities.add(new City(6L, "New York", 8550000));
cities.add(new City(7L, "Edinburgh", 464000));
cities.add(new City(8L, "Berlin", 3671000));
return cities;
}
}
CityDao contains the implementations of the findAll DAO method.
For simplicity reasons, we do not connect to the database but simply return
a list of City objects.
@ManagedBean
public class CityDao implements ICityDao {
CityDao is also a managed bean.
package com.zetcode.web;
import com.zetcode.bean.City;
import com.zetcode.service.ICityService;
import java.io.IOException;
import java.util.List;
import javax.inject.Inject;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@WebServlet(name = "GetCities", urlPatterns = {"/GetCities"})
public class GetCities extends HttpServlet {
@Inject
ICityService cityService;
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
response.setContentType("application/html;charset=UTF-8");
List<City> cities = cityService.getCities();
request.setAttribute("cities", cities);
RequestDispatcher dispatcher = request.getRequestDispatcher("listCities.jsp");
dispatcher.forward(request, response);
}
}
The GetCities servlet calls the city service's getCities
method and responds with a HTML pages which contains all cities in an HTML table.
@WebServlet(name = "GetCities", urlPatterns = {"/GetCities"})
The Java class is decorated with the @WebServlet annotation. It is mapped
to the GetCities URL pattern.
@Inject ICityService cityService;
With the @Inject annotation, we inject the CityService into
the CityService attribute.
response.setContentType("application/html;charset=UTF-8");
The servlet will output data in HTML and the encoding of the data is set to UTF-8.
List<City> cities = cityService.getCities();
request.setAttribute("cities", cities);
With CityService's getCities, we retrieve all
cities.
request.setAttribute("cities", cities);
We set the list into the request.
RequestDispatcher dispatcher = request.getRequestDispatcher("listCities.jsp");
dispatcher.forward(request, response);
Using the RequestDispatcher, we send the processing to the listCities.jsp
page. It is a template file which joins data with HTML and produces the final output to the
client.
<%@page contentType="text/html" pageEncoding="UTF-8"%>
<%@taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Cities</title>
</head>
<body>
<h2>Cities</h2>
<table>
<thead>
<tr>
<th>Id</th>
<th>Name</th>
<th>Population</th>
</tr>
</thead>
<tbody>
<c:forEach items="${cities}" var="city">
<tr>
<td>${city.id}</td>
<td>${city.name}</td>
<td>${city.population}</td>
</tr>
</c:forEach>
</tbody>
</table>
</body>
</html>
The listCities.jsp uses a c:forEach tag
to generate an HTML table from the supplied data.
<!DOCTYPE html>
<html>
<head>
<title>Home page</title>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<a href="GetCities">GetCities</a>
</body>
</html>
This is the home page. It contains a link to call the servlet.
In this tutorial we have shown how to include a Weld library in a Java Servlet web application and use to to manage dependencies.