企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
# Java Servlet Weld 教程 > 原文: [http://zetcode.com/articles/javaservletweld/](http://zetcode.com/articles/javaservletweld/) 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 库的帮助下使用依赖项注入。 ```java $ 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` ```java <?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` ```java <?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` ```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` ```java <?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` ```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` ```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 对象的方法,该方法是数据库的中间层。 ```java @ManagedBean public class CityService implements ICityService { ``` `@ManagedBean`是一个可选注解,指示`CityService`将由 Weld 管理。 ```java @Inject private ICityDao cityDao; ``` 使用`@Inject`注解,将`CityDao`注入`cityDao`属性。 `ICityDao.java` ```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` ```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`对象的列表。 ```java @ManagedBean public class CityDao implements ICityDao { ``` `CityDao`也是一个托管 bean。 `GetCities.java` ```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 页面。 ```java @WebServlet(name = "GetCities", urlPatterns = {"/GetCities"}) ``` Java 类用`@WebServlet`注解修饰。 它映射到`GetCities` URL 模式。 ```java @Inject ICityService cityService; ``` 使用`@Inject`注解,将`CityService`注入`CityService`属性。 ```java response.setContentType("application/html;charset=UTF-8"); ``` Servlet 将以 HTML 输出数据,并且数据的编码设置为 UTF-8。 ```java List<City> cities = cityService.getCities(); request.setAttribute("cities", cities); ``` 使用`CityService`的`getCities()`检索所有城市。 ```java request.setAttribute("cities", cities); ``` 我们将列表设置为请求。 ```java RequestDispatcher dispatcher = request.getRequestDispatcher("listCities.jsp"); dispatcher.forward(request, response); ``` 使用`RequestDispatcher`将处理发送到`listCities.jsp`页面。 它是一个模板文件,该模板文件将数据与 HTML 结合在一起并向客户端生成最终输出。 `listCities.jsp` ```java <%@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` ```java <!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 教程](/articles/javaservletservexml/), [Java Servlet 上传文件](/articles/javaservletuploadfile/), [Java Log4j 教程](/java/log4j/), [Java `HttpServletMapping`](/java/httpservletmapping/) , [Java Servlet RESTful 客户端](/articles/javaservletrestclient/), [Java `RequestDispatcher`](/java/requestdispatcher/) ,[从 Java Servlet 提供纯文本](/articles/javaservlettext/) , [Java Servlet 图像教程](/articles/javaservletimage/)或 [Java 教程](/lang/java/)。