XML-RPC - выдача исключений с сервера на клиент в Java - PullRequest
4 голосов
/ 10 мая 2011

Я впервые пишу здесь, и я не смог найти ответ на свой вопрос во время поиска, поэтому давайте посмотрим, смогу ли я правильно объяснить себя.

Я использую XML-RPC как часть большого проекта, но я представлю упрощенный код, в котором получаю тот же результат.

Соединение работает отлично, если я не выкидываю исключения. Моя проблема состоит в том, чтобы выдать исключение с сервера на клиент. Я получаю исключение XmlRpcException на стороне клиента, но его причина всегда null . Похоже, исключение потеряно при передаче. Есть идеи почему?

Мой сервер:

public class JavaServer { 

public Integer sum(int x, int y) throws Exception {
throw new MineException("ABABBABA");
}

public static void main (String [] args) {
try {

 System.out.println("Attempting to start XML-RPC Server...");
 WebServer server = new WebServer(80);
 XmlRpcServer xmlRpcServer = server.getXmlRpcServer();
 PropertyHandlerMapping phm = new PropertyHandlerMapping();
 phm.addHandler("test", JavaServer.class);
 xmlRpcServer.setHandlerMapping(phm);
 XmlRpcServerConfigImpl serverConfig = (XmlRpcServerConfigImpl) xmlRpcServer.getConfig();
    serverConfig.setEnabledForExceptions(true);

 server.start();
 System.out.println("Started successfully.");
 System.out.println("Accepting requests. (Halt program to stop.)");
} catch (Exception exception) {
 System.err.println("JavaServer: " + exception);
}}}

Мой клиент:

public static void main(String[] args) {

    XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
    try {
        config.setServerURL(new URL("http://localhost:80"));
        XmlRpcClient client = new XmlRpcClient();
        client.setConfig(config);           
        Object[] params = new Object[] { new Integer(38), new Integer(3), };

        Integer result = (Integer) client.execute("test.sum", params);
        System.out.println("Results " + result);
    } catch (XmlRpcException exception) {
        Throwable cause = exception.getCause();
        if(cause != null) {
            if(cause instanceof MineException) {
                System.out.println(((MineException)cause).getMessage());
            }
            else { System.out.println("Cause not instance of Exception"); }
        }
        else { System.out.println("Cause was null"); }
        } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
    }
}

Ответы [ 3 ]

3 голосов
/ 12 мая 2011

Я обнаружил, что с помощью реализации apache xml-rpc на клиенте и сервере можно генерировать пользовательские исключения с сервера и получать их на клиенте. Что-то просто нужно добавить в конфигурацию сервера и клиента.

Сервер:

WebServer server = new WebServer(80);
 XmlRpcServer xmlRpcServer = server.getXmlRpcServer();
 PropertyHandlerMapping phm = new PropertyHandlerMapping();
 phm.addHandler("test", JavaServer.class);
 xmlRpcServer.setHandlerMapping(phm);
 XmlRpcServerConfigImpl serverConfig = (XmlRpcServerConfigImpl) xmlRpcServer.getConfig();
    serverConfig.setEnabledForExceptions(true);
    serverConfig.setEnabledForExtensions(true); //Add this line
 server.start();

Клиент:

XmlRpcClientConfigImpl config = new XmlRpcClientConfigImpl();
    try {
        config.setServerURL(new URL("http://localhost:80"));
        config.setEnabledForExceptions(true);
        config.setEnabledForExtensions(true); //Add this line
        XmlRpcClient client = new XmlRpcClient();
        client.setConfig(config);                           
        Object[] params = new Object[] { new Integer(11), new Integer(3), };
        Integer result = (Integer) client.execute(config,"test.sum", params);
        System.out.println("Results " + result);
    } catch (XmlRpcException exception) {
        System.out.println(exception.getMessage());
        Throwable cause = exception.getCause();
        if(cause != null) {
            if(cause instanceof MyException) {
                System.out.println(((MyException)cause).getMessage());
            }
            else { System.out.println("Cause not instance of Exception."); }
        }
        else { System.out.println("Cause was null."); }
        } catch (Exception e) {
        // TODO Auto-generated catch block
        e.printStackTrace();

Тогда все работает как положено.

3 голосов
/ 14 ноября 2012

Еще один (надеюсь, полезный) совет.

Итак, вы хотите включить расширения для исключений, но вы запускаете службу в сервлете внутри (полноценного) веб-сервера, например, Apache Tomcat. Затем необходимо включить расширения и исключения, настроив их в файле web.xml (WEB-INF \ web.xml):

<servlet>
  <servlet-name>My_XMLRPC_Servlet</servlet-name>
    <servlet-class>com.stackoverflow.server.MyXmlRpcServlet</servlet-class>
      <init-param>
        <param-name>enabledForExtensions</param-name>
        <param-value>true</param-value>
      </init-param>
      <init-param>
        <param-name>enabledForExceptions</param-name>
        <param-value>true</param-value>
      </init-param>
        ...
</servlet>
2 голосов
/ 11 мая 2011

После небольшого исследования я нашел ответ ... краткий ответ заключается в том, что невозможно отправлять пользовательские исключения через канал XMLRPC в соответствии со спецификацией XMLRPC :

Может ли структура содержать другие члены, кроме faultCode и faultString?

Структура сбоев может не содержать членов, отличных от указанных.Это верно для всех других структур.Мы считаем, что спецификация является достаточно гибкой, чтобы все разумные потребности в передаче данных могли быть учтены в указанных структурах.Если вы твердо убеждены в том, что это не так, пожалуйста, опубликуйте сообщение в группе обсуждения.

Не очень короткий ответ заключается в том, что это можно сделать другим способом, если сервер выбрасывает вместоXmlRpcException.

public Integer sum(int x, int y) throws XmlRpcException {
   // XmlRpcException(exceptionCode,exceptionMessage)
   throw new XmlRpcException(1,"Message");
}

А на стороне клиента:

catch (XmlRpcException exception) {
    System.out.println("Exception code: " + exception.code);
    System.out.println("Exception message: " + exception.getMessage());
}

Если клиент и сервер соглашаются использовать определенные коды, исключение можно идентифицировать с помощью кода и сообщения.Это не совсем обычные исключения, но это самое близкое, что мы можем получить.

...