Java Servlet Weld 教程

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 保存城市对象的数据。 它具有三个属性:idnamepopulation

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's 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 服务 XML 教程Java Servlet 上传文件Java Log4j 教程Java HttpServletMapping Java Servlet RESTful 客户端Java Servlet 图像教程Java 教程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程