WCF client errors when consuming Java services - java

I'm currently working on a project where I need to consume a Java webservice. If I connect to the service using old webservices (asmx) it works fine. However, If I try to do the same thing with a WCF client I get the following error:
The content type text/xml; charset=utf-8 of the response message does not match the content type of the binding (application/soap+xml; charset=utf-8). If using a custom encoder, be sure that the IsContentTypeSupported method is implemented properly.
My is very simple and it looks like the following:
//classic web service
OldSkoolService.HelloService serviceCall = new esb_wsdlsample.OldSkoolService.HelloService();
Console.WriteLine(serviceCall.SoapVersion);
Console.WriteLine(serviceCall.sayHello("something"));
HelloServiceClient prototypeClient = new HelloServiceClient();
var serviceChannel = prototypeClient.ChannelFactory;
Console.WriteLine(serviceChannel.Endpoint.Binding.MessageVersion);
Console.WriteLine(prototypeClient.sayHello("somethinge")); //<-- Error occurs here
The the binding/endpoint config file is quite simple as well:
<bindings>
<customBinding>
<binding name="Soap12Binding">
<textMessageEncoding messageVersion="Soap12"/>
<httpTransport />
</binding>
</customBinding>
</bindings>
<client>
<endpoint address="http://10.10.6.51:7001/esb/HelloService" behaviorConfiguration=""
binding="customBinding" bindingConfiguration="Soap12Binding" contract="Prototype.ESB.HelloService"
name="HelloServicePort" />
</client>
As a side note I'm trying to use soap 1.2, because I need to be able to catch exceptions from the service.

Based on your error message, it simply means that your Server response message is SOAP 1.1, while you expect SOAP 1.2.
You'll have to change to SOAP 1.1 on the client (using BasicHttpBinding, at least do it to test and see if it works that way).

While it isn't required by the SOAP 1.2 specification, it is recommended (i.e. SHOULD) that SOAP messages use a content-type of application/soap+xml.
You should change this on the server side. If not, then I think that you will have to fiddle around with the textMessageEncoding binding element in the config file to make it accept the text/xml content-type.

Related

Apache CXF: sending a byte array

We are sending a byte array to a REST API we do not control.
The REST API requires the byte array to be sent as the body.
The code is as follows:
String path = "/dokumente/angebote/{angebotsId}/unterlagen/{dokumentId}";
WebTarget target = createWebTarget().path(path).resolveTemplate("angebotsId", angebotsId).resolveTemplate("dokumentId", documentType);
try (ResponseHandler handler = new ResponseHandler(
target.request(document.getMimeType()).header("Content-Type", document.getMimeType())
.post(Entity.entity(MY_BYTE_ARRAY))) {
Response response = handler.getResponse();
...
}
This has worked well so far, we have been using JBoss and RestEasy. We have now migrated our application to OpenLiberty, which means that Apache CXF will be used as JAX-RS implementation.
And since the migration, the implementation does not work anymore. We found out that if we use a wrapper class like that:
MyWrapper myByteArrayWrapper = new MyWrapper();
myByteArrayWrapper.setData(MY_BYTE_ARRAY));
.post(Entity.entity(myByteArrayWrapper))
then Apache CXF will successfully transfer the byte array, but this does not comply to the API definition of the service we are calling.
Has anybody succeeded in getting a byte[] upload running with Apache CXF?
The problem was that OLP (in contrast to JBoss) used chunked transfer. The server that we called did not support that. Chunked transfer was now enabled on the other server, and now everything works.

Get SOAP XML or header in Axis web service (IBM WebSphere 7)

I have in my hands, an Axis web service that supposedly receives SOAP requests and gives SOAP responses. This was done by some other people and I don't have any prior experience with Apache Axis.
When a test program sends a sample SOAP request to the web service, at first org.apache.axis2.transport.http.AxisServlet.doPost received the request as an HTTP POST request. It then goes through some processing in Axis2 API which finally calls our own code through reflection.
At this entry point of our code, we can only get what is defined with the axis namespace in the SOAP XML request. What I need is to get the request header or the entire SOAP XML request, through Java.
A skeleton sample structure is:
<Envelope xmlns:axis="soap-service-url">
<Header>
some-header-content
</Header>
<Body>
<axis:request>
<axis:input0>sometext</axis:input0>
<axis:input1>othertext</axis:input1>
</axis:request>
</Body>
</Envelope>
At the entry point of our code, we are only getting sometext and othertext as Strings. My goal is to get the header, that is some-header-content, but I'll be happy if I can just get the entire SOAP XML.
I had been trying to find a solution for quite some time (searched a lot, looked up similar questions in SO), but the more I read up the more I get confused. I have tried:
Invoke org.apache.axis.client.Call object created from org.apache.axis.client.Service.createCall() - this always results in a NullPointerException no matter what configuration I try for setTargetEndpointAddress, setOperationName, setSOAPActionURI etc.
MessageContext.getCurrentContext() - returns null
Thought about adding a Handler but I'm not sure how to do it, or even how the Handler will pass the header content to where I actually need it (aren't handlers asynchronous?)
It is possible my understanding of how Axis functions is wrong and I need to approach this problem differently.

Losing attachments in Axis2 response

I'm trying to send an attachment to client from Axis2 web service. The problem is that the message context, which client receives from the service, does not contain any attachments, though the last one seems to add it.
Here is the brief code of both sides.
Service:
MessageContext inMC = MessageContext.getCurrentMessageContext();
OperationContext operationContext = inMC.getOperationContext();
MessageContext outMC = operationContext.getMessageContext(WSDLConstants.MESSAGE_LABEL_OUT_VALUE);
DataHandler handler = new DataHandler (new FileDataSource("C://goods.xml"));
String attachID = outMC.addAttachment(handler);
OMElement idElem = factory.createOMElement("doc", ns);
idElem.addAttribute("href", "cid:" + attachID, ns);
Client (trying to receive attachment):
MessageContext mcResponse = operationClient.getMessageContext(WSDLConstants.MESSAGE_LABEL_IN_VALUE);
SOAPBody body = mcResponse.getEnvelope().getBody();
OMElement attachElem = body.getFirstChildWithName (new QName("doc"));
String attachID = attachElem.getAttributeValue (new QName("href"));
attachID = attachID.replaceFirst("cid:", "");
DataHandler dataHandler = mcResponse.getAttachment(attachID);
getAttachment() method returns null. In case of debugging the client application, IDE shows, that attachment map in input message context does not contain any elements (size=0). The OMElement object (idElem), which contains attachment id, is received and read by client normally (debug showed cid). The parameters enableSwA, cacheAttachments, attachmentDIR, sizeThreshold are set both in services.xml and programming part of client. What is wrong with the message context?
Thanks a lot for any suggestions.
Upd: TCPmon showed the following content.
Request to service:
<?xml version="1.0" encoding="UTF-8"?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><getXMLFile xmlns="http://axis2.apache.org"><filename>goods.xml</filename></getXMLFile></soapenv:Body></soapenv:Envelope>
I guess it's ok :)
Response from service:
109
<?xml version='1.0' encoding='UTF-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body><doc href="cid:d06f3b36afdfcbd2e135ecfbcad05ee602661262b059ed38#apache.org"></doc></soapenv:Body></soapenv:Envelope>
0
I apologize for a bit simple questions, but where the attachment should be reflected? I guess, if the service send an attachment, the SOAP message contains binary data, isn't it?
I checked also for putting the attachment into message context on service side - it's OK, I can get it there back from context after adding.
you can use tcpmon[1] to trace the http message and isolate the problem.
Anyway the better method for handling attachments is to use MTOM. Which can be used with data binding frameworks like ADB[2], or with POJO as well.
thanks,
Amila.
[1] http://ws.apache.org/commons/tcpmon/
[2] http://amilachinthaka.blogspot.com/2009/01/using-mtom-with-axis2.html
The problem was solved. The trouble was on the service side. TCPmon showed there was no attachments in responce message. However, the same example service works fine. After checking and comparing every operation on my service, it came out that programming part is not the reason either. The only one was left - service settings. So, the reason is that settings fields in service.xml file on the service, which require boolean type, does not allow any additional symbols. My mistake:
Incorrect:
<parameter name="enableSwA">
true
</parameter>
Correct:
<parameter name="enableSwA">true</parameter>

How to filter outbound routing using Mule ESB?

I have a instance of Mule that is configured to process xml responses from a third party provider. Recently the provider has moved to a new revision and hence changed the xml response. Now I need a way to identify if the response is a v1 or v2 implementation and call the appropriate endpoint on my side to process the response.
What I have currently is:
<service name="processResponse">
...
<outbound>
<pass-through-router>
<cxf:outbound-endpoint address="..." clientClass="..." wsdlPort="..." wsdlLocation="..." operation="..."/>
</pass-through-router>
</outbound>
</service>
I would prefer to add a filter in mule to identify the revision of the 3rd party (perhaps through the xml namespace in the response), and then call the appropriate class. I cannot find any good examples of this.
Can someone provide an example of how this could be solved?
Take a look at this example, where some version transformation is demonstrated.
I suspect the most straight forward means is a filtered route using an xpath filter. First define vm services for each version. Next you'll filter to them through a service with following outbound endpoint. A catch all is always a good idea.
<outbound>
<filtering-router>
<vm:outbound-endpoint ref="Version1"/>
<expression-filter evaluator="jxpath" expression="/your/version1/xpath/descriminator"/>
</filtering-router>
<filtering-router>
<vm:outbound-endpoint ref="Version2"/>
<expression-filter evaluator="jxpath" expression="/your/version2/xpath/descriminator"/>
</filtering-router>
<forwarding-catch-all-strategy>
<stdio:outbound-endpoint system="ERR"/>
</forwarding-catch-all-strategy>
</outbound>

MTOM Request / Non-MTOM Response

We have a pretty simple WS, implemented using annotations. We would like to be able to call this from clients both supporting MTOM/XOP and not.
Right now, it is annotated simply #MTOM.
It takes a request containing (amongst others) a base64Binary element, and serves a response containing a single boolean element.
Calling it is no problem, either with our without MTOM - it works. Only, the response, even though it doesn't contain any MTOM:able elements has headers declaring it a MTOM message, which chokes the non-MTOM client.
<tran:headers xsi:type="http:HttpResponseHeaders" xmlns:http="http://www.bea.com/wli/sb/transports/http" xmlns:tran="http://www.bea.com/wli/sb/transports" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<tran:user-header name="X-Powered-By" value="Servlet/2.5 JSP/2.1"/>
<http:Content-Type>
multipart/related;start="<rootpart*c3e56707-113c-47f9-b02c-2a3234766dc4#example.jaxws.sun.com>";type="application/xop+xml";boundary="uuid:c3e56707-113c-47f9-b02c-2a3234766dc4";start-info="text/xml"
</http:Content-Type>
<http:Date>Tue, 11 May 2010 07:27:51 GMT</http:Date>
<http:Transfer-Encoding>chunked</http:Transfer-Encoding>
</tran:headers>
Does anyone know how to get the service to always respond with a non-MTOM response while still accepting both MTOM and non-MTOM requests?
The service runs on a WebLogic 10.3 server...
Kind regards,
Lars
Actually what I found odd was if I don't put an #MTOM the resulting message never returns a mutli-part message. However, the web service still accepts the MTOM data in WebSphere.

Categories

Resources