@Resource 未注入 CDI 托管 bean,但在 web servlet 中工作正常
@Resource not injected in CDI managed bean, but works fine in web servlet
我正在尝试使用 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。提前致谢!
解决方案是借助 Wildfly 的控制台创建一个非 XA 数据源。这也包括向 Web 容器添加 mysql 连接器驱动程序。之后,您可以轻松地将数据源注入到您的应用程序中。
问题解决了,但是servlet应该是瘦的。使用分层架构,您可以获得更加灵活的解决方案。
我正在尝试使用 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。提前致谢!
解决方案是借助 Wildfly 的控制台创建一个非 XA 数据源。这也包括向 Web 容器添加 mysql 连接器驱动程序。之后,您可以轻松地将数据源注入到您的应用程序中。
问题解决了,但是servlet应该是瘦的。使用分层架构,您可以获得更加灵活的解决方案。