Java Servlet Weld 教程展示了如何在带有 Weld 的 Java Servlet 中使用依赖注入。 我们将 Weld 与 Tomcat Web 服务器一起使用。
依赖注入
依赖项注入(DI)是一种技术,其中一个对象提供另一个对象的依赖项。 对于 Java 应用,它是一个特定的库,可以将依赖项注入到类中。 DI 的主要优点是耦合松散且易于使用。 DI 使类更具凝聚力,因为它们的职责更少。
Java EE 通过引入上下文和依赖注入(CDI)规范来标准化依赖注入。 它是依赖项注入和上下文生命周期管理的标准。
@Inject
注解
@Inject
注解用于将依赖项注入 Java 类。 可以使用@ManagedBean
注解来装饰要注入的依赖项。
焊接
Weld 是 Java EE 平台的 CDI 的参考实现。 Weld 已集成到许多 Java EE 应用服务器中,例如 WildFly,JBoss,GlassFish 等。 Weld 也可以在普通的 servlet 容器(Tomcat,Jetty)或 Java SE 中使用。
Java Servlet Weld 示例
在以下 Web 应用中,我们创建一个 servlet,该 servlet 返回 HTML 文件中的城市对象列表。 在应用中,我们在 Weld 库的帮助下使用依赖项注入。
$ 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
这是项目结构。
pom.xml
<?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>
这是 Maven POM 文件。 javax.servlet-api
工件用于 servlet。 weld-servlet-shaded
依赖项使 Weld 可以在 Servlet 容器中运行。 jstl
将 JSTL 库添加到项目中。 JSTL 包括一组用于 JSP 应用的有用标签。 maven-war-plugin
负责收集 Web 应用的所有工件依赖项,类和资源,并将它们打包到 Web 应用存档(WAR)中。
context.xml
<?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>
在 Tomcat context.xml
文件中,我们定义上下文路径并注册 Weld 的BeanManager
工厂。
City.java
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);
}
}
City
bean 保存城市对象的数据。 它具有三个属性:id
,name
和population
。
beans.xml
<?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>
在WEB-INF
目录中,我们有一个空的beans.xml
文件。 它是 CDI 的部署描述符。 它可用于配置拦截器,装饰器和其他内容。 即使没有配置,我们也需要添加一个空的beans.xml
来注册 CDI。
ICityService.java
package com.zetcode.service;
import com.zetcode.bean.City;
import java.util.List;
public interface ICityService {
public List<City> getCities();
}
ICityService
包含getCities()
合同方法。
CityService.java
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
包含ICityService
接口的实现。 服务类调用 DAO 对象的方法,该方法是数据库的中间层。
@ManagedBean
public class CityService implements ICityService {
@ManagedBean
是一个可选注解,指示CityService
将由 Weld 管理。
@Inject
private ICityDao cityDao;
使用@Inject
注解,将CityDao
注入cityDao
属性。
ICityDao.java
package com.zetcode.dao;
import com.zetcode.bean.City;
import java.util.List;
public interface ICityDao {
public List<City> findAll();
}
这里我们有 DAO findAll()
合约方法。
CityDao.java
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
包含findAll()
DAO 方法的实现。 为简单起见,我们不连接数据库,而只是返回City
对象的列表。
@ManagedBean
public class CityDao implements ICityDao {
CityDao
也是一个托管 bean。
GetCities.java
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);
}
}
在GetCities
servlet 调用城市服务的getCities()
方法和响应与包含在 HTML 表中的所有城市中的 HTML 页面。
@WebServlet(name = "GetCities", urlPatterns = {"/GetCities"})
Java 类用@WebServlet
注解修饰。 它映射到GetCities
URL 模式。
@Inject
ICityService cityService;
使用@Inject
注解,将CityService
注入CityService
属性。
response.setContentType("application/html;charset=UTF-8");
Servlet 将以 HTML 输出数据,并且数据的编码设置为 UTF-8。
List<City> cities = cityService.getCities();
request.setAttribute("cities", cities);
使用CityService
的getCities()
检索所有城市。
request.setAttribute("cities", cities);
我们将列表设置为请求。
RequestDispatcher dispatcher = request.getRequestDispatcher("listCities.jsp");
dispatcher.forward(request, response);
使用RequestDispatcher
将处理发送到listCities.jsp
页面。 它是一个模板文件,该模板文件将数据与 HTML 结合在一起并向客户端生成最终输出。
listCities.jsp
<%@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>
listCities.jsp
使用c:forEach
标签从提供的数据生成 HTML 表。
index.html
<!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>
这是主页。 它包含一个调用 servlet 的链接。
在本教程中,我们展示了如何在 Java Servlet Web 应用中包含 Weld 库以及如何使用它来管理依赖项。
您可能也对以下相关教程感兴趣: Java Servlet 服务 XML 教程, Java Servlet 上传文件, Java Log4j 教程, Java HttpServletMapping
, Java Servlet RESTful 客户端, Java RequestDispatcher
,从 Java Servlet 提供纯文本 , Java Servlet 图像教程或 Java 教程。