简体   繁体   English

XML-RPC状态Java服务器无法正常工作

[英]XML-RPC stateful Java server not working

I dont understand what I may be doing wrong. 我不明白我在做什么错。

I am trying to follow this tutorial to implement a stateful servlet. 我正在尝试按照教程来实现有状态servlet。

My org.apache.xmlrpc.webserver.XmlRpcServlet.properties looks like this: 我的org.apache.xmlrpc.webserver.XmlRpcServlet.properties看起来像这样:

com.mydbm.MyDBM=com.mydbm.MyDBMImpl

This is MyDBM interface and MyDBMImpl Code: 这是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;
}

The following is my Handler Code: 以下是我的处理程序代码:

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;
    }
}

} }

This is my Server Code: 这是我的服务器代码:

    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 content extract: 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>

And finally here is my Client Code: 最后是我的客户代码:

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();
      }
  }

} }

Error log: 错误日志:

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

The dbm.setUp(..) method executes correctly and creates the dbConn object on the server. dbm.setUp(..)方法正确执行并在服务器上创建dbConn对象。 However, when I ran the dbm.getDatabases(), I get a null pointer exception and I believe its because the server creates a new instance of the handler instead of using the initial state of the handler. 但是,当我运行dbm.getDatabases()时,我得到了一个空指针异常,并且我相信这是因为服务器创建了处理程序的新实例,而不是使用处理程序的初始状态。 I am not expert in this but from this tutorial, I was expecting that once dbConn has been set-up, I would be able to use it in subsequent invocations . 我不是这方面的专家,但是从教程开始,我期望dbConn设置好之后,就可以在以后的调用中使用它了。

Someone kindly assist,I have no Idea where I may be going wrong as I followed the instructions from the tutorial to the latter. 有人帮助,我不知道我按照教程中的指示可能会出错的地方。

I have tried to past as much information and I would be willing to add more if necessary. 我已尝试传递尽可能多的信息,并在必要时愿意添加更多信息。

Thank you. 谢谢。

Yes your problem is, that the server creates a new instance every time. 是的,您的问题是,服务器每次都会创建一个新实例。 I ran into the same problem and solved it with an extra handler class in which i invoked the instance of the earlier handler. 我遇到了同样的问题,并通过一个额外的处理程序类解决了该问题,在该类中,我调用了较早的处理程序的实例。

Something like this: 像这样:

public class MyDBMXmlRpcRequestProcessorFactoryFactoryWrapper
{
   private MyDBMXmlRpcRequestProcessorFactoryFactoryWrapper attribute;
   public MyDBMXmlRpcRequestProcessorFactoryFactoryWrapper(class param)
   {
        attribute = MyDBMXmlRpcRequestProcessorFactoryFactory(param);
   }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM