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.