【问题标题】:@Resource not injected in CDI managed bean, but works fine in web servlet@Resource 未注入 CDI 托管 bean,但在 web servlet 中工作正常
【发布时间】:2016-02-29 08:37:38
【问题描述】:

我正在尝试使用 JDBC 从我的数据库中读取很多名字,并且它在我的名为 HelloServlet 的 servlet 中运行良好。我实际上可以用一堆名字来响应一个 GET 请求。

@WebServlet(name = "helloServlet", value = "/hello")
public class HelloServlet extends HttpServlet {
    @Resource(lookup = "java:global/employeesDS")
    DataSource ds;

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        List<String> list = new ArrayList<>();

        try(Connection connection = ds.getConnection()) {
            Statement statement = connection.createStatement();
            ResultSet result = statement.executeQuery("SELECT first_name FROM employees");

            while(result.next()) {
                list.add(result.getString(1));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        PrintWriter pw = resp.getWriter();
        for(String name : list) {
            pw.write(name + " " );
        }
    }
}

当我在 CDI 托管 bean 中尝试相同的代码时,ds 仍然是 null,导致 NullPointerException 麻烦:

@Named("dataFetchBean")
@RequestScoped
public class DataFetchBean {
    @Resource(lookup = "java:global/employeesDS")
    DataSource ds;
    List<String> questions;

    public List<String> getQuestions() {
        try(Connection connection = ds.getConnection()) {
            Statement statement = connection.createStatement();
            ResultSet result = statement.executeQuery("SELECT first_name FROM employees");

            while(result.next()) {
                questions.add(result.getString(1));
            }
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return questions;
    }
}

如果相关,这是我的 web.xml 文件:

<?xml version="1.0" encoding="UTF-8"?>
<web-app 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/web-app_3_1.xsd"
         version="3.1">
    <data-source>
        <name>java:global/employeesDS</name>
        <class-name>com.mysql.jdbc.jdbc2.optional.MysqlDataSource</class-name>
        <server-name>localhost</server-name>
        <port-number>3306</port-number>
        <database-name>employees</database-name>
        <user>root</user>
        <password />
    </data-source>

    <servlet>
        <servlet-name>Faces Servlet</servlet-name>
        <servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Faces Servlet</servlet-name>
        <url-pattern>*.xhtml</url-pattern>
    </servlet-mapping>
</web-app>

这是我尝试在其中使用 DataFetchBean CDI 托管 bean 的 index.xhtml 文档:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://xmlns.jcp.org/jsf/html"
      xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
      xmlns:f="http://xmlns.jcp.org/jsf/core" xmlns:c="http://java.sun.com/jsp/jstl/core">
<h:head>
    <title>Hello, JDBC!</title>
</h:head>
<h:body>
    <table>
        <tr>
            <td>First name</td>
        </tr>
        <c:forEach items="#{dataFetchBean.questions}" var="question">
            <tr>
                <td>
                    #{question}
                </td>
            </tr>
        </c:forEach>
    </table>
</h:body>
</html>

我使用的是 Wildfly 10.0.10。提前致谢!

【问题讨论】:

  • 你在哪里以及如何使用这个 bean?如果您在 servlet 中注入和使用 bean,它会起作用吗?
  • 我在 c:forEach JSF 标记中的 .xhtml 文档中使用它,如下所示:items=#{dataFetchBean.questions}, var="question"
  • 应该可以通过@Resource 将资源注入CDI bean。我的猜测是,您定义数据源的方式会导致问题。您可以尝试在 Wildfly 的子系统中定义数据源,而不是在 Web 应用程序中。
  • 我明白了,谢谢!我已经尝试过了,但是我正在使用 IntelliJ,由于某种原因,当我通过 IntelliJ 在 Wildfly 上运行我的应用程序时,我无法访问 Wildfly 控制台,这让我的工作更加困难。
  • 我刚刚在 Wildfly 的子系统中配置了一个数据源,但遗憾的是没有任何改变。

标签: jakarta-ee jdbc resources cdi managed-bean


【解决方案1】:

解决方案是在 Wildfly 控制台的帮助下创建一个非 XA 数据源。这也包括向 Web 容器添加 mysql 连接器驱动程序。之后,您可以轻松地将数据源注入到您的应用程序中。

【讨论】:

    【解决方案2】:

    问题已解决,但 servlet 应该很精简。使用分层架构,您可以获得更灵活的解决方案。

    【讨论】:

    • 感谢您的提示!我想我将使用 Hibernate 来访问我的数据库并将数据写入我的数据库。我应该将其背后的逻辑放入 EJB 中,还是应该使用我在书中找到的数据访问对象模式?
    • 将 EJB-s 用作服务外观(用于容器管理的安全性 + 事务)并将注入的对象用作业务 + 数据访问层元素,以最大限度地提高灵活性。
    • 感谢您的提示!
    猜你喜欢
    • 1970-01-01
    • 2015-08-06
    • 1970-01-01
    • 2018-06-22
    • 2013-09-01
    • 2011-10-16
    • 2015-04-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多