I have a Silverlight client that I need to call a web service. The web service is built in Java and uses XOP encoding to attach binary messages to some of its calls. However, the Silverlight service only uses calls that do not include any binary encoding. However, since I have no control over the web service, I must still deal with the XOP multi-part message - (an example of one is below).
Example response from web service (data stripped out)
HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
X-Powered-By: Servlet 2.5; JBoss-5.0/JBossWeb-2.1
Content-Type: multipart/related; type="application/xop+xml"; boundary="uuid:890535d9-d11f-4dfb-8393-789e20ea8064"; start="<root.message#cxf.apache.org>"; start-info="text/xml"
Date: Thu, 27 Jan 2011 22:03:09 GMT
Content-Length: 47247
--uuid:890535d9-d11f-4dfb-8393-789e20ea8064
Content-Type: application/xop+xml; charset=UTF-8; type="text/xml";
Content-Transfer-Encoding: binary
Content-ID: <root.message#cxf.apache.org>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns2:Response xmlns:ns2="http://tempuri.com/"></ns2:Response>
</soap:Body>
</soap:Envelope>
--uuid:890535d9-d11f-4dfb-8393-789e20ea8064--
Our current implementation manually constructs a soap message using string replacement and uses the WebClient class to post the request and download the response as a string. We're then stuck with manually parsing the data as XML. This is ok, but it's a bit difficult, and we have REST services available for that anyway; I'd really like the service proxy to respond with objects.
What I'd really like to do is implement a custom behavior that will intercept the message before the WS stack tries to deserialize the SOAP and remove the XOP gunk, but so far I have found nothing that will allow me to do such a thing.
The way I see it, I have a few options:
Create a proxy service on the server (that I control) that will resubmit the request to the Java service and can actually handle the XOP. This option has performance implications that I'd like to avoid.
Implement a custom MessageEncodingBindingElement, MessageEncoderFactory, and MessageEncoder that will handle the XOP. This option seems like the best at first, but since I cannot extend the TextMessageEncoderFactory or TextMessageEncoder (they are internal classes) I basically would need to rewrite the entire message encoding from scratch (Thank you very much Microsoft!).
Leave the thing as it is.
Are there any options that I'm not seeing?
Nope, there's no other alternatives.
I've decided to implement a pass-through ashx proxy that will use the WebClient.DownloadString() method then parse out just the SOAP and plug that into the response. It should be flexible enough, and best of all, I can just use the autogenerated proxy classes from Silverlight, then just make the endpoint use my ashx proxy - which makes maintenance much simpler.
Related
I am using a very particular language named “Magik”, I used to use MSXML2 to run web services but in one of my projects I failed to use MSXML, I tried a lot of thing to make it work from changing MSXML.DLL and testing different version of MSXML, using MSXMLHttpServer and all the things you may think of, I somehow ate MSDN website but didn’t find anything helpfull.
Now I am looking for other ways of calling a SOAP webservice, someone said you may post your XML to web method address by parsing and using a query string, But I didn’t succeed to do so.
I can also negotiate via TCP/IP, Can I send my XML to a web service using a TCP/IP connection?
If there is any other way that do the job I really appreciate it.
Currently I am connecting Magik to a Java application and when I need to call a web service I send my request to that Java application (there is a Jar file which creates a data-bus between a Magik session and a Java Application) I have also wrote the Java part using Axis technology. But this is a very hard job and I should change a lot of things to only keep my project up and match with a small change in web service that I consume.
Using MSXML were so easy formerly, sadly it does not work now!
First note that you can not use GET to call SOAP web services only POST will work with SOAP, GET can be used for REST but you mentioned SOAP only.
I can introduce you two method that you may use to call a web service instead of your MSXML which does not work anymore.
Using Test Form (Web Service Test Page)
You may ask your .Net web services provider to create a test form for his own web service and you create a query string which suppose to emulate the data on the form, actually you are using the web services tester page to send your data via query string to it and it will complete the rest for you.
Using TCPIP
use a TCP/IP Connection, in this method you need to create a header above your xml to set the parameters that a web service consumer should fill (remember MSXML and Content-Type, Content-Length, SOAPAction, Host, …….)
then translate your string to a byte vector since all programming language which can create a TCPIP Socket just accept a byte vector while inputing or outputing data to that connection. after translating the string you are ready to send the data to your web services address.
take a look at the following example of how you may create a string to send to a TCPIP socket.
POST /globalweather.asmx HTTP/1.1
Host: www.webservicex.net
Content-Type: text/xml; charset=utf-8
Content-Length: length
SOAPAction: "http://www.webserviceX.NET/GetCitiesByCountry"
<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:xsi=http://www.w3.org/2001/XMLSchema-instance
xmlns:xsd=http://www.w3.org/2001/XMLSchema
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<GetCitiesByCountry xmlns="http://www.webserviceX.NET">
<CountryName>Egypt</CountryName>
</GetCitiesByCountry>
</soap:Body>
</soap:Envelope>
You may send above string to http://www.webservicex.net/globalweather.asmx
You may check to following link if you need detailed information about how to consume a web service using TCPIP
http://www.codeproject.com/Articles/312530/Calling-Webservice-Using-TCP-IP-from-any-Programmi
Is there possible create SoapUI Mock service that not return response but it is just closing connection?
I'm quite sure what you're asking for is not possible with SoapUI MockServices. There are some extensive possibilities involving scripting, and it is even possible to access the underlying javax.servlet.http.HttpServletRequest and Response objects. Have a look here for details:
http://www.soapui.org/Service-Mocking/creating-dynamic-mockservices.html
Using scripting, it is possible to write a mock service request handler like this in SoapUI that just resets and closes the output stream:
mockRequest.getHttpResponse().reset();
mockRequest.getHttpResponse().getOutputStream().close();
But the client will still see a HTTP response header like this generated by the servlet container:
HTTP/1.1 200 OK
Content-Length: 0
Server: Jetty(6.1.x)
It is generally not possible to abort the connection immediately from inside a servlet (which is what SoapUI mock services are built upon). Have a look here about this topic:
How to close a HTTP connection from the HttpServlet
I'd use something completely different than SoapUI, most likely a scripting technology like PHP or Perl to achieve what you're asking for.
I'm using Apache CXF (2.6.1) in my java application to consume 3rd party Web Service. But I have a problem with it, in particular if I use JAXB for databinding while stubs generation my client will always send requests with "header" like "--uuid:e47f145b-38f7-4402-8eec-657d71bc8ad4..." (see client request below), i.e. besides XML part there is some special info...
It looks like this special info causes error reply from server "Content is not allowed in prolog" (see server response below), i.e. server is not expecting such body. What is interesting here is that if I generate stubs using XMLBEANS for databinding everything starts to work just fine (and there is no such "special" info in request body, only XML). After some googling I suspect that my client for some reason tries to use MTOM (with JAXB) and I don't know how to turn it off. I've already tried the following to turn MTOM off (with no luck):
((BindingProvider)port).getRequestContext().put("mtom-enabled", Boolean.FALSE);
((BindingProvider)port).getRequestContext().put("write.attachments", Boolean.FALSE);
((BindingProvider)port).setMTOMEnabled(false);
Please help I would really want to move to JAXB since it's much more compact in comparison with XMLBEANS...
Client code:
AdminServiceV2 ws = new AdminServiceV2();
AdminV2 port = ws.getAdminPortV2();
Client client = ClientProxy.getClient(port);
HTTPConduit http = (HTTPConduit) client.getConduit();
AuthorizationPolicy authorizationPolicy = new AuthorizationPolicy();
authorizationPolicy.setUserName("user1");
authorizationPolicy.setPassword("password1");
authorizationPolicy.setAuthorizationType("Basic");
http.setAuthorization(authorizationPolicy);
try {
port.getUsersInfo("user1");
} catch (Exception e) {
e.printStackTrace();
}
Client request:
--uuid:e47f145b-38f7-4402-8eec-657d71bc8ad4
Content-Type: text/xml; charset=UTF-8; type="text/xml";
Content-Transfer-Encoding: binary
Content-ID: <root.message#cxf.apache.org>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"><soap:Body><ns2:getUsersInfo xmlns:ns2="http://service.admin.ws.five9.com/v2/"><userNamePattern>user1</userNamePattern></ns2:getUsersInfo></soap:Body></soap:Envelope>
--uuid:e47f145b-38f7-4402-8eec-657d71bc8ad4--
Server response:
<env:Envelope xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'><env:Header></env:Header><env:Body><env:Fault xmlns:env='http://schemas.xmlsoap.org/soap/envelope/'><faultcode>env:Client</faultcode><faultstring>org.xml.sax.SAXParseException: Content is not allowed in prolog.</faultstring></env:Fault></env:Body></env:Envelope>
Thanks,
Konstantin
No CXF request ever starts normally with --uuid. That is part-way through a multi-part HTTP message. With or without MTOM, a normal SOAP message consists of an HTTP header followed by the XML content. If it's MTOM, the HTTP header declared multipart, and then there are multipart separators and sub-headers.
If you are using a custom front-end to ask for 'plain XML' messages without the usual required HTTP headers, then that, combined with MTOM, might have the undesirable effect at hand.
JAXB will generally only enable MTOM if you have #XmlMimeType("application/octet-stream") annotations(s). You should also look at the WSDL/XSD for the service and see if it has xmime annotations in there.
See the CXF MTOM doc for more details.
You haven't specified the CXF version or how you configured your CXF client endpoint. You might get better assistance by sending all that data to the CXF user mailing list.
The question was answered on CXF user mailing list by Daniel Kulp, for details see
http://cxf.547215.n5.nabble.com/Apache-CXF-2-6-1-Client-gets-Content-is-not-allowed-in-prolog-td5713009.html#a5713055. In short the problem was with WSDL (it contains swaRefs) that forces CXF to send messages like with attachments. Workaround was also provided...
I'm trying to generate a web service call from my iphone app.
I'm working with web services for the the first time.
I realize that an SOAP request would something like this:
My actual web service is not on local.
POST /MyFirstWebService.asmx HTTP/1.1 Host: localhost
Content-Type: text/xml; charset=utf-8 Content-Length: length
SOAPAction: "http://tempuri.org/HelloWorld"
<?xml version="1.0" encoding="utf-8"?> <soap:Envelope
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance>
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<HelloWorld xmlns="http://tempuri.org/" /> </soap:Body> </soap:Envelope>
I want the string hello world returned from the web service.
What is the best way to do this?
I have also read about a framework called JSON.
Can that be useful here?
This link provides simple explaination of how to consume web service in iphone it also explains simple post simple Get and SOAP
Consuming Web Services in iPhone Applications
Difference Between Soap and REST
SOAP and RESTful web services have a very different philosophy from each other. SOAP is really a protocol for XML-based distributed computing, whereas REST adheres much more closely to a bare metal, web-based design. SOAP by itself is not that complex; it can get complex, however, when it is used with its numerous extensions (guilt by association).
To summarize their strengths and weaknesses:
* SOAP *
Pros:
Langauge, platform, and transport agnostic
Designed to handle distributed computing environments
Is the prevailing standard for web services, and hence has better support from other standards (WSDL, WS-*) and tooling from vendors
Built-in error handling (faults)
Extensibility
Cons:
Conceptually more difficult, more "heavy-weight" than REST
More verbose
Harder to develop, requires tools
* REST *
Pros:
Language and platform agnostic
Much simpler to develop than SOAP
Small learning curve, less reliance on tools
Concise, no need for additional messaging layer
Closer in design and philosophy to the Web
Cons:
Assumes a point-to-point communication model--not usable for distributed computing environment where message may go through one or more intermediaries
Lack of standards support for security, policy, reliable messaging, etc., so services that have more sophisticated requirements are harder to develop ("roll your own")
Tied to the HTTP transport model
If I need a web service to pass back and forth a complex object, is there a reason I should prefer SOAP over REST? Here is an example of the possible SOAP message:
<soap:Envelope>
<soap:Header>
<Credentials>
<User>Joe</User>
<Password>abc123</Password>
</Credentials>
</soap:Header>
<soap:Body>
<MyComplexBusinessObject>
<Search>
<First>Joe</First>
<Last>Smith</Last>
</Search>
...
...
</MyComplexBusinessObject>
</soap:Body>
</soap:Envelope>
Using REST, I would be asking the client to POST the following xml and authenticate using Basic Authentication:
<MyComplexBusinessObject>
<Search>
<First>Joe</First>
<Last>Smith</Last>
</Search>
...
...
</MyComplexBusinessObject>
The SOAP message is slightly more complicated, but not by much. They are still both XML, but SOAP comes with a WSDL and most programming environments will generate proxy classes for you. However, most people I talk to say I should use REST instead because it's easier to use. But I don't see how SOAP is any harder to use.
Am I missing something?
Your first requirement of "passing back and forth a complex object" constrains your architecture to eliminate many of the benefits of REST. SOAP is designed for accessing remote objects, REST is not. REST supports passing media-types as simple as text/plain, which is far more primitive than dealing with an object.
If you haven't seen it already, this question and its answers cover most of the REST vs SOAP issues.
One major benefit of REST is that all you need to call and use it is a browser and a HTTP stack - pretty much every device and machine has that. So if ease of use and reach are you main goal - use REST.
One of the major benefits of SOAP is that you have a WSDL service description and you can pretty much discover the service automatically, and generate a useable client proxy from that service description (generate the service calls, the necessary data types for the methods and so forth).
So if discoverability and a strict, formal service description are more important to you, use SOAP (with the downside that you need a full-fledged SOAP client to call your service - your web browser won't be sufficient).
SOAP isn't harder to use - but it's just not quite as "pervasive" in terms of being available - any browser can call a REST service and get an answer - but then it needs to parse and interpret that response. SOAP gets nice data structure, but you need a SOAP client for this.
I view SOAP and REST as orthogonal APIs, designed to do different things.
SOAP is basically a fancy RPC, so if you want to send a computation request over to the server and get the result back, you use SOAP. If it would be local, it would be a method call to an object instance.
REST is a way to create, retrieve, update and delete remote objects, not in the sense of POO, using a uniform API. If it would be local, it would be like working with a file.
So they actually respond to different needs. You can bastardize one to do the work of the other, but you mangle the meanings.
If you develop both the service and the client, using SOAP is as easy as REST (actually easier).
You may prefer SOAP over REST if these conditions meet:
The entire service API is complex, not just one object.
The service is used within a relatively small network, and performance is not an important requirement.
You decide to spend the minimum amount of time to develop both the service and the API documentation.