[英]How to inject a datasource in a Java file using @Resource annotation? Works fine in a Servlet though
I am trying to inject a datasource in a Java file using @Resource annotation and it gives me a NullPointerException.我正在尝试使用 @Resource 注释在 Java 文件中注入一个数据源,它给了我一个 NullPointerException。 The thing that is puzzling me is that when I put this @Resource in a Servlet it works fine and I get the data from the DB.
令我困惑的是,当我将这个 @Resource 放在 Servlet 中时,它工作正常并且我从数据库中获取数据。 As part of refactoring effort I am just trying to move this @Resource annotation calling from my Servlet Controller to a service class and it gives me NPE.
作为重构工作的一部分,我只是想将这个 @Resource 注释调用从我的 Servlet 控制器移动到一个服务类,它给了我 NPE。
@WebServlet(name = "ProductPageController", urlPatterns = {"/" + AppConstants.PRODUCT_PAGE_CONTROLLER})
public class ProductPageController extends HttpServlet {
private static final Logger LOG = Logger.getLogger(ProductPageController.class);
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
processRequest(request, response);
}
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
processRequest(request, response);
}
protected void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
LOG.debug("Into the ProductPageController...");
//fetch the product from the db based on productId parameter
String productId = GenericUtils.getParameter(request, "productId");
request.setAttribute("product", new ProductService().getProduct(new Integer(productId)));
//show the page now
showPage(request, response, PRODUCT_PAGE_URL);
}
private void showPage(HttpServletRequest request, HttpServletResponse response, String viewName) throws ServletException, IOException {
LOG.debug("Displaying " + viewName + " page now...");
request.getServletContext().getRequestDispatcher(viewName).forward(request, response);
}
}
public class ProductService {
private static final Logger LOG = Logger.getLogger(ProductService.class);
@Resource(name = "jdbc/istore-db")
private DataSource dataSource;
public Product getProduct(int productId) {
Product product = null;
try {
product = new MasterDao(dataSource).getProduct(productId);
} catch (SQLException sqle) {
LOG.error("Exception while fetching product based on productId: " + productId);
LOG.error(sqle);
}
LOG.debug("product = " + product);
return product;
}
}
java.lang.NullPointerException
at com.istore.dao.MasterDao.getProduct(MasterDao.java:75)
at com.istore.service.ProductService.getProduct(ProductService.java:38)
at com.istore.web.controllers.ProductPageController.processRequest(ProductPageController.java:35)
at com.istore.web.controllers.ProductPageController.doGet(ProductPageController.java:22)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:618)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:725)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:501)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:610)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:537)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1085)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:658)
at org.apache.coyote.http11.Http11NioProtocol$Http11ConnectionHandler.process(Http11NioProtocol.java:222)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1556)
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1513)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
If you are instantiating the class by yourself with new ProductService()
then no dependency injection will happen.如果您使用
new ProductService()
自己实例化该类,则不会发生依赖注入。
you will have to inject ProductService in your servlet.您必须在您的 servlet 中注入 ProductService。
@Inject
private ProductService productService
You can bypass the problem of resource injection not working with @Resource annotation by using directly the JNDI API您可以直接使用 JNDI API 来绕过资源注入无法使用 @Resource 注解的问题
try {
Context initialCtxt = new InitialContext();
dataSource = (DataSource) initialCtxt.lookup("java:comp/env/jdbc/istore-db");
} catch (NamingException ex) {
LOG.error("Exception while fetching the data source: jdbc/istore-db");
LOG.error(ex);
}
and you can place this code in your ProductService
constructor您可以将此代码放在您的
ProductService
构造函数中
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.