SOAP запрос на Java не работает, но работает на PHP - PullRequest
0 голосов
/ 26 апреля 2020

Я пытался найти информацию об этом, но я не могу найти что-либо, связанное именно с моей проблемой.

Когда я звоню soap, используя PHP класс SoapClient , запрос работает отлично. Но когда я пытаюсь сделать то же самое на Java, я получаю исключение, говоря, что URL не принимает POST, я видел людей, создающих Soap вызовы на PHP с помощью Curl, используя POST, но я не действительно не знаю, что делает SoapClient.

В любом случае, это PHP Код:

$url    = 'https://mail.myzimbra.mx/service/wsdl/ZimbraAdminService.wsdl';
$soap_client = new SoapClient($url, array("soap_version" => SOAP_1_1,"trace" => 1));

$ns = 'urn:zimbra';

$headerbody = array('context' => '');

//Create Soap Header.       
$header = new SOAPHeader($ns, 'RequestorCredentials', $headerbody);       

//set the Headers of Soap Client.
$soap_client->__setSoapHeaders($header);

$AuthRequestObjectXML  = '<AuthRequest xmlns="urn:zimbraAdmin" password="password">
        <account by="adminName">user@zimbra.mx</account>
    </AuthRequest>';


$AuthRequestObject  = new SoapVar($AuthRequestObjectXML,XSD_ANYXML);

$objResponse = $soap_client->__soapCall(
        'AuthRequest',
       array($AuthRequestObject)
   );

$lastrequest = $soap_client->__getLastRequest();


$token = $objResponse->authToken;

Это не фантастика, но она выполняет свою работу.

Теперь на java (Я сделал несколько попыток, но это последняя попытка):

String send = "<soap:Envelope xmlns:soap=\"http://www.w3.org/2003/05/soap-envelope\">" +
              "<soap:Header xmlns=\"urn:zimbra\">" +
              "<context></context>" +
              "</soap:Header>" +
              "<soap:Body>" +
              "<AuthRequest xmlns=\"urn:zimbraAdmin\" password=\""+ ZIMBRA_ADMIN_PASSWORD +"\">" +
              "<account by=\"adminName\">"+ ZIMBRA_ADMIN_ACCOUNT +"</account>" +
              "</AuthRequest>" +
              "</soap:Body>" +
              "</soap:Envelope>";

      SOAPConnectionFactory sfc = SOAPConnectionFactory.newInstance();
      SOAPConnection connection = sfc.createConnection();
      InputStream is = new ByteArrayInputStream(send.getBytes());
      SOAPMessage request = MessageFactory.newInstance().createMessage(null, is);

      request.writeTo(System.out); //Here it prints my envelop, which is formed just like the PHP one.

      URL endpoint = new URL(URL_ZIMBRA_ADMIN_WSDL);
      SOAPMessage response = connection.call(request, endpoint);

Переменные соответствуют PHP значениям, они точно такие же, я проверил эту сотню раз.

Но калла занимает несколько секунд, наверное, около 20, затем я получаю

com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Bad response: (400HTTP method POST is not supported by this URL
    at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.call(HttpSOAPConnection.java:149)
    at com.project.services.ZimbraService.getToken(ZimbraService.java:79)

*more stuff*

CAUSE:

com.sun.xml.internal.messaging.saaj.SOAPExceptionImpl: Bad response: (400HTTP method POST is not supported by this URL
    at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.post(HttpSOAPConnection.java:264)
    at com.sun.xml.internal.messaging.saaj.client.p2p.HttpSOAPConnection.call(HttpSOAPConnection.java:145)

Я пробовал несколько вещей, например, изменение протокола на SOAPConstants.SOAP_1_2_PROTOCOL поэтому тип содержимого заголовка запроса - изменить на application / soap + xml, но, похоже, ничего не работает, я всегда получаю POST, не допускаемый исключением URL. Также пробовал другой поток, который я читал об изменении URL, чтобы удалить часть файла wsdl, но не повезло.

Итак, если он работает на PHP, почему он не работает на java? Я запускаю оба сценария на одной машине.

1 Ответ

1 голос
/ 26 апреля 2020

PHP s SoapClient имеет то, что называется «режимом WSDL», где, когда вы даете ему URL для WSDL, он загружает этот WSDL и извлекает реальный конец URL-адрес точки из WSDL.

Java SOAPConnection не имеет «режима WSDL», поэтому необходимо указать реальный URL-адрес конечной точки для call() метод, а не URL-адрес WSDL.

Если вы не знаете реальный URL-адрес конечной точки, сделайте то, что делает SoapClient, загрузите WSDL самостоятельно и посмотрите на него. URL-адрес конечной точки будет в конце.

Начиная с пример WSDL :

  ...

  <service name="EndorsementSearchService">
    <documentation>snowboarding-info.com Endorsement Service</documentation> 
    <port name="GetEndorsingBoarderPort"
          binding="es:EndorsementSearchSoapBinding">
      <soap:address location="http://www.snowboard-info.com/EndorsementSearch"/>
    </port>
  </service>

</definitions>

Здесь реальный URL-адрес конечной точки: http://www.snowboard-info.com/EndorsementSearch

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...