首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法使用ApacheTomcat 8注入数据源

无法使用ApacheTomcat 8注入数据源
EN

Stack Overflow用户
提问于 2016-11-14 06:36:46
回答 1查看 127关注 0票数 0

这是我第一次尝试使用DataSource,这是JSF及其与JDBC的集成。

我在context.xml中定义了资源(在META文件夹中),并在web.xml中添加了一个资源引用<resource-ref> (包含在WEB文件夹中)。然后我创建了ManagedBean。

这是我在Netbeans中创建的数据库的截图。

AddressBean.java

代码语言:javascript
复制
package com.addressbook.pkg;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import javax.annotation.Resource;
import javax.faces.bean.ManagedBean;
import javax.sql.DataSource;
import javax.sql.rowset.CachedRowSet;

@ManagedBean(name="addressBean")
public class AddressBean {
    private String firstName;
    private String lastName;
    private String street;
    private String city;
    private String state;
    private String zipcode;

    //allow server to inject the DataSource
    @Resource(name="jdbc/addressbook")
    DataSource dataSource;

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getState() {
        return state;
    }

    public void setState(String state) {
        this.state = state;
    }

    public String getZipcode() {
        return zipcode;
    }

    public void setZipcode(String zipcode) {
        this.zipcode = zipcode;
    }

    public ResultSet getAddresses()throws SQLException{

        //check whether dataSource was injected by the server
        if(dataSource == null){
            throw new SQLException("Unable to obtain DataSource");
        }

        //obtain a connection from the connection pool
        Connection connection = dataSource.getConnection();

        //check whether the connection was successful
        if(connection == null){
            throw new SQLException("Unable to connect to DataSource");
        }

        try{
            //create a PreparedStatement to insert a new address book entry
            String SQL = "SELECT firstname, lastname,street, city, state,zip FROM addresses ORDER BY LASTNAME, FIRSTNAME";
            PreparedStatement getAddresses = connection.prepareStatement(SQL);

            CachedRowSet rowSet = new com.sun.rowset.CachedRowSetImpl();
            rowSet.populate(getAddresses.executeQuery());
            return rowSet;
        }finally{
            connection.close();
        }
    }//end of getAddresses()


    public String save()throws SQLException{
        //check whether the datasource was injected by the server
        if(dataSource == null){
            throw new SQLException("Unable to obtain DataSource");
        }
        //obtain connection from the connection pool
        Connection connection = dataSource.getConnection();

        //check whether connection  was successful
        if(connection == null){
            throw new SQLException("Unable to connect to DataSource");
        }
        try{
            String SQL = "INSERT INTO addresses(firstname,lastname,street,city,zip)VALUES(?,?,?,?,?,?)";
            PreparedStatement addEntry = connection.prepareStatement(SQL);

            //specify the PreparedStatement's arguments
            addEntry.setString(1,getFirstName());
            addEntry.setString(2, getLastName());
            addEntry.setString(3,getStreet());
            addEntry.setString(4,getCity());
            addEntry.setString(5, getState());
            addEntry.setString(6,getZipcode());

            addEntry.executeUpdate(); //insert the entry
            return "index"; //go back to index.xhtml page
        }
        finally{
            connection.close();
        }
    }

}

Context.xml

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<Context path="/addressbook">
    <Resource name="jdbc/addressbook" auth="Container" type="javax.sql.DataSource"
               maxActive="50" maxIdle="30" maxWait="10000"
               username="root" password=""
               driverClassName="com.mysql.jdbc.Driver"
               url="jdbc:mysql://localhost:3306/testdb"/>

</Context>

web.xml

代码语言:javascript
复制
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="3.1" 
         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">
    <context-param>
        <param-name>javax.faces.PROJECT_STAGE</param-name>
        <param-value>Development</param-value>
    </context-param>
    <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>/faces/*</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>faces/index.xhtml</welcome-file>
    </welcome-file-list>

    <resource-ref>
    <description>MySQL Datasource example</description>
    <res-ref-name>jdbc/addressbook</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
  </resource-ref>

</web-app>

我已经将正确的资源名称和数据库详细信息放在了context.xmlweb.xml上,但是当我运行该项目时,我得到了一个SQLException

代码语言:javascript
复制
java.sql.SQLException: Unable to obtain DataSource
    at com.addressbook.pkg.AddressBean.getAddresses(AddressBean.java:78)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:497)
    at javax.el.BeanELResolver.getValue(BeanELResolver.java:97)
    at com.sun.faces.el.DemuxCompositeELResolver._getValue(DemuxCompositeELResolver.java:176)
    at com.sun.faces.el.DemuxCompositeELResolver.getValue(DemuxCompositeELResolver.java:203)
    at org.apache.el.parser.AstValue.getValue(AstValue.java:169)
    at org.apache.el.ValueExpressionImpl.getValue(ValueExpressionImpl.java:184)
    at com.sun.faces.facelets.el.TagValueExpression.getValue(TagValueExpression.java:109)
    at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:194)
    at javax.faces.component.ComponentStateHelper.eval(ComponentStateHelper.java:182)
    at javax.faces.component.UIData.getValue(UIData.java:732)
    at javax.faces.component.UIData.getDataModel(UIData.java:1822)
    at javax.faces.component.UIData.setRowIndexWithoutRowStatePreserved(UIData.java:484)
    at javax.faces.component.UIData.setRowIndex(UIData.java:473)
    at com.sun.faces.renderkit.html_basic.TableRenderer.encodeBegin(TableRenderer.java:81)
    at javax.faces.component.UIComponentBase.encodeBegin(UIComponentBase.java:864)
    at javax.faces.component.UIData.encodeBegin(UIData.java:1133)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1854)
    at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1859)
    at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:456)
    at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:133)
    at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:120)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:219)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:647)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:292)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:240)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:207)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:212)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
    at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:616)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:528)
    at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1100)
    at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:687)
    at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.doRun(AprEndpoint.java:2508)
    at org.apache.tomcat.util.net.AprEndpoint$SocketProcessor.run(AprEndpoint.java:2497)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

SQLException中可以看出,它没有正确地获取数据源,而且很可能是NULL

我不知道为什么会是空的。

我可以毫无问题地连接到localhost:8080。我检查了我的数据库,并证实它正在运行并连接到服务器。

顺便说一下,我使用的是MysqlApacheTomcat 8.0

希望你能帮上忙。

谢谢。

EN

回答 1

Stack Overflow用户

发布于 2016-11-15 15:02:12

我终于找到了解决问题的办法。我所做的不是仅仅添加@Resource(name="jdbc/addressbook")注释,而是简单地使用Context类和lookup()方法来引用DataSource

代码语言:javascript
复制
    //@Resource(name="jdbc/addressbook")
    DataSource dataSource;

public ResultSet getAddresses()throws SQLException{


        try {
            Context ctx = new InitialContext();
            dataSource = (DataSource) ctx.lookup("java:comp/env/jdbc/addressbook");
        } catch (NamingException e) {
            JOptionPane.showMessageDialog(null,"Error: "+e.getMessage());
        }

        //check whether dataSource was injected by the server
        if(dataSource == null){
            throw new SQLException("Can't get DataSource");
        }

        //obtain a connection from the connection pool
        Connection connection = dataSource.getConnection();

        //check whether the connection was successful
        if(connection == null){
            throw new SQLException("Unable to connect to DataSource");
        }

        try{
            //create a PreparedStatement to insert a new address book entry
            String SQL = "SELECT firstname, lastname,street, city, state,zip FROM addresses ORDER BY LASTNAME, FIRSTNAME";
            PreparedStatement getAddresses = connection.prepareStatement(SQL);

            CachedRowSet rowSet = new com.sun.rowset.CachedRowSetImpl();
            rowSet.populate(getAddresses.executeQuery());
            return rowSet;
        }finally{
            connection.close();
        }
    }//end of getAddresses()

只需在try-catch块中使用lookup()方法,我的web应用程序就能够获得DataSource jdbc/addressbook

如果您中的一些人遇到使用DataSource注释获取@Resource的问题,这应该可以作为替代解决方案。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40583117

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档