问题
I've been trying to find information about this, but I can't seem to find anything related exactly to my problem.
When I make a soap call, using PHP class SoapClient, the request works perfectly. But when I try to do the same on Java, I get an exception, saying the URL doesn't accept POST, I've seen people building Soap calls on PHP with Curl, using POST, but I don't really know what SoapClient do.
Anyway, this is the PHP Code:
$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;
It isn't fancy, but it gets the job done.
Now, on java (I've done several attempts, but this is the last I tried) :
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);
Variables do match PHP values, they are exactly the same, I've verified this a hundred times.
But the calla takes some seconds, about 20, I guess, then I get
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)
I've tried several things, like changing protocol to SOAPConstants.SOAP_1_2_PROTOCOL, so request header content type is change to application/soap+xml, but nothing seems to work, I always get the POST not allowed by URL exception. Also tried some other thread I read about changing the URL to remove the wsdl file part, but no luck.
So, if it works on PHP, why doesn't it work on java? I'm running both scripts on the same machine.
回答1:
PHP's SoapClient has what is called "WSDL mode", where when you give it the URL for the WSDL, it downloads that WSDL, and extracts the real end point URL from the WSDL.
Java's SOAPConnection does not have a "WSDL mode", so you need to provide the real end point URL to the call()
method, not the WSDL URL.
If you don't know the real end point URL, do what SoapClient
does, download the WSDL yourself and look at it. The end point URL will be at the end.
From example 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>
Here the real end point URL is: http://www.snowboard-info.com/EndorsementSearch
来源:https://stackoverflow.com/questions/61435573/soap-request-on-java-not-working-but-does-on-php