这是我第一次尝试使用DataSource,而且是JSF的新功能,以及它与JDBC的集成。
我在context.xml中定义了资源(在META-INF文件夹中),并在web.xml中添加了资源引用<resource-ref>
(包含在WEB-INF文件夹中)。然后我创建了ManagedBean。
这是我在Netbeans中创建的数据库的屏幕截图。
AddressBean.java
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中
<?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
<?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.xml
和web.xml
上都设置了正确的资源名称和数据库详细信息,但是当我运行项目时,我得到SQLException
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
。我检查了我的数据库并确认它已运行并连接到服务器。
顺便说一下,我使用 Mysql 和 ApacheTomcat 8.0
我希望你能提供帮助。
谢谢。
答案 0 :(得分:0)
我终于找到了解决问题的方法。我只是使用@Resource(name="jdbc/addressbook")
类和Context
方法来引用lookup()
DataSource
注释。
//@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()
方法,我的网络应用就可以获得DataSource
jdbc/addressbook
。
这可以作为替代解决方案,因为有些人在单独使用DataSource
注释获取@Resource
时会遇到问题。