我不明白我可能做错了什么。
我正在尝试按照本教程来实现有状态的 servlet。
我的org.apache.xmlrpc.webserver.XmlRpcServlet.properties看起来像这样:
com.mydbm.MyDBM=com.mydbm.MyDBMImpl
这是 MyDBM 接口和 MyDBMImpl 代码:
public interface MyDBM {
public void setUp(DBConnection dbc) throws ClassNotFoundException,
SQLException, JSchException;
public ArrayList<Database> getDatabases() throws SQLException;
.....
}
public class MyDBMImpl implements MyDBM {
private volatile Connection connection;
private volatile Class<?> driverClass;
private volatile Statement statement;
private volatile DBConnection dbConn;
@Override
public void setUp(DBConnection dbc) throws ClassNotFoundException,
SQLException, JSchException {
this.dbConn = dbc;
if (dbConn.SSHEnabled()) {
LOG.info("SSH Requested, enabling...");
setUpSshConnection();
LOG.info("SSH enabled!");
} else {
LOG.info("SSH not Requested, skipping...");
}
setupConnection();
}
.....
@Override
public ArrayList<Database> getDatabases() throws SQLException {
switch (dbConn.getDatabaseType()) { // NULL POINTER EXCEPTION HERE,
case MYSQL:
return getDatabasesMySQL();
case MSSQLSERVER:
return getDatabasesMSServerSQL();
case SQLITE:
return getDatabasesSQLite();
case SYBASE:
return getDatabasesSyBase();
case POSTGRESQL:
return getDatabasesPostgreSQL();
case ORACLE:
return getDatabasesOracle();
}
return null;
}
以下是我的处理程序代码:
public class MyDBMXmlRpcRequestProcessorFactoryFactory implements
RequestProcessorFactoryFactory {
private final RequestProcessorFactory factory = new MyDBMRequestProcessorFactory();
private final MyDBM dbm;
public MyDBMXmlRpcRequestProcessorFactoryFactory(
MyDBM dbm) {
this.dbm = dbm;
}
@Override
public RequestProcessorFactory getRequestProcessorFactory(Class aClass)
throws XmlRpcException {
return factory;
}
private class MyDBMRequestProcessorFactory implements
RequestProcessorFactory {
@Override
public Object getRequestProcessor(XmlRpcRequest xmlRpcRequest)
throws XmlRpcException {
return dbm;
}
}
}
这是我的服务器代码:
public class Server {
private static final int port = 8080;
public static void main(String[] args) throws Exception {
WebServer webServer = new WebServer(port);
XmlRpcServer xmlRpcServer = webServer.getXmlRpcServer();
PropertyHandlerMapping phm = new PropertyHandlerMapping();
MyDBM dbm = new MyDBMImpl();
phm.setRequestProcessorFactoryFactory(new MyDBMXmlRpcRequestProcessorFactoryFactory(
dbm));
phm.setVoidMethodEnabled(true);
phm.addHandler(MyDBM.class.getName(),
MyDBM.class);
xmlRpcServer.setHandlerMapping(phm);
XmlRpcServerConfigImpl serverConfig = (XmlRpcServerConfigImpl) xmlRpcServer
.getConfig();
serverConfig.setEnabledForExtensions(true);
serverConfig.setContentLengthOptional(false);
webServer.start();
}
}
web.xml 内容提取:
<web-app>
<!-- SOME PARTS LEFT OUT ->
<servlet>
<servlet-name>XmlRpcServlet</servlet-name>
<servlet-class>org.apache.xmlrpc.webserver.XmlRpcServlet</servlet-class>
<init-param>
<param-name>enabledForExtensions</param-name>
<param-value>true</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>XmlRpcServlet</servlet-name>
<url-pattern>/xmlrpc</url-pattern>
</servlet-mapping>
</web-app>
最后是我的客户代码:
public class MyClient {
public static void main(String[] args) throws Exception {
// create configuration
XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
config.setServerURL(new URL("http://127.0.0.1:8080/xmlrpctest/xmlrpc"));
config.setEnabledForExtensions(true);
config.setConnectionTimeout(60 * 1000);
config.setReplyTimeout(60 * 1000);
XmlRpcClient client = new XmlRpcClient();
// use Commons HttpClient as transport
client.setTransportFactory(
new XmlRpcCommonsTransportFactory(client));
// set configuration
client.setConfig(config);
// make a call using dynamic proxy
ClientFactory factory = new ClientFactory(client);
MyDBM dbm = (MyDBM)factory.newInstance(MyDBM.class);
try {
dbm.setUp(new DBConnection("myconn", DatabaseType.MYSQL, "localhost", 0, "userid", "secret", "mysql")); // Connection is setup correctly
ArrayList<Database> dbs = dbm.getDatabases(); // Fails with NullPointerException
} catch(Exception e) {
System.out.println(e.getCause().getMessage());
e.printStackTrace();
}
}
}
错误日志:
Sep 27, 2013 11:49:26 AM com.myapp.MyDBMImpl setUp
INFO: SSH not Requested, skipping...
jdbc:mysql://localhost/mysql?user=userid&password=secret
Sep 27, 2013 11:49:26 AM org.apache.xmlrpc.server.XmlRpcErrorLogger log
SEVERE: Failed to invoke method getDatabases in class com.myapp.MyDBMImpl: null
org.apache.xmlrpc.common.XmlRpcInvocationException: Failed to invoke method getDatabases in class com.myapp.MyDBMImpl: null
dbm.setUp(..) 方法正确执行并在服务器上创建 dbConn 对象。但是,当我运行 dbm.getDatabases() 时,我得到一个空指针异常,我相信这是因为服务器创建了一个新的处理程序实例,而不是使用处理程序的初始状态。我不是这方面的专家,但是从本教程中,我期望一旦设置了 dbConn,我就可以在后续调用中使用它。
有人帮忙,我不知道我可能会出错,因为我按照教程中的说明进行操作。
我试图过去尽可能多的信息,如有必要,我愿意添加更多信息。
谢谢你。