I am sure this is just pilot error, but cannot find a solution. Have a jax-ws web service with a soap payload operation that includes an attachment. Here is a snippet of the schema doc. This is the type defined:
<xs:complexType name="BinaryAttachmentType">
<xs:simpleContent>
<xs:restriction base="xmime:base64Binary">
<xs:attribute ref="xmime:contentType" use="required" />
</xs:restriction>
</xs:simpleContent>
</xs:complexType>
Embedded in this element definition:
<xs:element name="Contact">
<xs:complexType>
<xs:sequence>
<!-- removed other elements -->
<xs:element name="Attachment" type="BinaryAttachmentType" minOccurs="0" maxOccurs="1"/>
</xs:sequence>
</xs:complexType>
</xs:element
Using soapUI, SOAP looks like:
<hsn:Contact>
<!-- other elements -->
<hsn:Attachment xm:contentType="image/jpeg">cid:323665198529</hsn:Attachment>
</hsn:Contact>
Attached file in soapUI:
When I look at http from log:
http Header:
"Content-Type: multipart/related; type="text/xml"; start="<rootpart#soapui.org>"; boundary="----=_Part_15_23791896.1485382707426""
"SOAPAction: "http://hsn.us.banner.hsntech.com/Level1Request""
"MIME-Version: 1.0"
"Content-Length: 104164"
"Host: localhost:7001"
"User-Agent: Apache-HttpClient/4.1.1 (java 1.5)"
"------=_Part_15_23791896.1485382707426"
"Content-Type: text/xml; charset=UTF-8"
"Content-Transfer-Encoding: 8bit"
"Content-ID: <rootpart#soapui.org>"
in SOAP body, see attachment element with base64-encoded file:
<hsn:AttachmentFileName>test1.jpg</hsn:AttachmentFileName>
<hsn:Attachment xm:contentType="image/jpeg">/9j/4AAQSkZJRgABAQEAYABgAAD .. rest of base64 encoding
then after SOAP message, encoded attachment again:
------=_Part_15_23791896.1485382707426
Content-Type: image/jpeg;
name=Foo.jpg
Content-Transfer-Encoding: binary
Content-ID: <Foo.jpg>
Content-Disposition: attachment; name=Foo.jpg; filename=Foo.jpg
(... encoded attachment again )
[0xff][0xd8][0xff][0xe0][0x0][0x10]JFIF[0x0][0x1][0x1][0x1][0x0]`[0x0]`[0x0][0x0][0xff][0xdb][0x0]C[0x0][\n]
So, why the file encoded twice in the request? Thanks.
Check that Enable MTOM is set to True in the Request Properties:
Related
I'm trying to send an e-mail from within a C++ application via a Microsoft Exchange 2010 server. For this, I use the EWS protocol using the library ews-cpp.
The following trivial example, based on the one from https://github.com/otris/ews-cpp/blob/master/examples/send_message.cpp, is failing (mail addresses and credentials stripped from my actual code):
#include <iostream>
#include <ews/ews.hpp>
struct {
std::string domain = "mailserver";
std::string username = "...";
std::string password = "...";
std::string server_uri = "https://mailserver/EWS/Exchange.asmx";
} env;
int main()
{
ews::set_up();
try
{
auto service = ews::service(env.server_uri, env.domain, env.username,
env.password);
service.set_request_server_version(ews::server_version::exchange_2010_sp2);
auto message = ews::message();
message.set_subject("Test mail from outer space");
std::vector<ews::mailbox> recipients;
recipients.push_back(ews::mailbox("..."));
message.set_to_recipients(recipients);
auto text = ews::body("This is a test.");
message.set_body(text);
service.create_item(message,
ews::message_disposition::send_and_save_copy);
}
catch (ews::schema_validation_error& exc)
{
std::cout << exc.what() << std::endl;
std::cout << exc.violation() << std::endl;
}
ews::tear_down();
return 0;
}
The raw SOAP request is as follows (indentation added by me):
<m:CreateItem MessageDisposition="SendAndSaveCopy">
<m:Items>
<t:Message>
<t:Subject>Test mail from outer space</t:Subject>
<t:ToRecipients>
<t:Mailbox>
<t:EmailAddress>...</t:EmailAddress>
</t:Mailbox>
</t:ToRecipients>
<t:Body BodyType="Text">This is a test.</t:Body>
</t:Message>
</m:Items>
</m:CreateItem>
The function create_item throws an ews::schema_validation_error which is caught in the above code, printing:
The request failed schema validation
The element 'Message' in namespace ‘http://schemas.microsoft.com/exchange/services/2006/types’ has invalid child element 'Body' in namespace 'http://schemas.microsoft.com/exchange/services/2006/types'. List of possible elements expected: 'CcRecipients, BccRecipients, IsReadReceiptRequested, IsDeliveryReceiptRequested, ConversationIndex, ConversationTopic, From, InternetMessageId, IsRead, IsResponseRequested, References, ReplyTo, ReceivedBy, ReceivedRepresenting' in Namespace 'http://schemas.microsoft.com/exchange/services/2006/types'.
In other words, EWS doesn't expect <t:Body> within <t:Message>.
So, when leaving out that element in the SOAP request (comment out message.set_body(text)), the mail is sent smoothly. However, a mail without a body doesn't make much sense, does it?
I thought that the problem might be the fact that ews-cpp was written for Exchange 2013 (and that the schema changed between 2010 and 2013 in this regard). So I digged into the schema, which each Exchange server serves at /ews/types.xsd, to see if the schema allows such a child element.
In the schema definition file, I found the definition of the type MessageType (which is the type of the Message element we are talking about):
<xs:complexType name="MessageType">
<xs:complexContent>
<xs:extension base="t:ItemType">
<xs:sequence>
<xs:element name="Sender" minOccurs="0" type="t:SingleRecipientType"/>
<xs:element name="ToRecipients" type="t:ArrayOfRecipientsType" minOccurs="0"/>
<xs:element name="CcRecipients" type="t:ArrayOfRecipientsType" minOccurs="0"/>
<xs:element name="BccRecipients" type="t:ArrayOfRecipientsType" minOccurs="0"/>
<xs:element name="IsReadReceiptRequested" type="xs:boolean" minOccurs="0"/>
<xs:element name="IsDeliveryReceiptRequested" type="xs:boolean" minOccurs="0"/>
<xs:element name="ConversationIndex" type="xs:base64Binary" minOccurs="0"/>
<xs:element name="ConversationTopic" type="xs:string" minOccurs="0"/>
<xs:element name="From" type="t:SingleRecipientType" minOccurs="0"/>
<xs:element name="InternetMessageId" type="xs:string" minOccurs="0"/>
<xs:element name="IsRead" type="xs:boolean" minOccurs="0"/>
<xs:element name="IsResponseRequested" type="xs:boolean" minOccurs="0"/>
<xs:element name="References" type="xs:string" minOccurs="0"/>
<xs:element name="ReplyTo" type="t:ArrayOfRecipientsType" minOccurs="0"/>
<xs:element name="ReceivedBy" type="t:SingleRecipientType" minOccurs="0"/>
<xs:element name="ReceivedRepresenting" type="t:SingleRecipientType" minOccurs="0"/>
</xs:sequence>
</xs:extension>
</xs:complexContent>
</xs:complexType>
As you can see, there is no Body child element, but MessageType is based on ItemType, which is defined as follows (excerpt):
<xs:complexType name="ItemType">
<xs:sequence>
<xs:element name="MimeContent" type="t:MimeContentType" minOccurs="0"/>
<xs:element name="ItemId" type="t:ItemIdType" minOccurs="0"/>
<xs:element name="ParentFolderId" type="t:FolderIdType" minOccurs="0"/>
<xs:element name="ItemClass" type="t:ItemClassType" minOccurs="0"/>
<xs:element name="Subject" type="xs:string" minOccurs="0"/>
<xs:element name="Sensitivity" type="t:SensitivityChoicesType" minOccurs="0"/>
<xs:element name="Body" type="t:BodyType" minOccurs="0"/>
<xs:element name="Attachments" type="t:NonEmptyArrayOfAttachmentsType" minOccurs="0"/>
[...]
</xs:sequence>
</xs:complexType>
As you can see, it accepts the Body element as a child.
Note that the Subject element is also defined in the ItemType and not in MessageType, and that is accepted by EWS in the above code snippet.
What might be the cause of this strange validation failure?
Found the solution myself:
For the element Message, which is based on Item according to the schema definition, EWS first expects all child elements for Item, followed by the Message-specific child elements.
This sounds very insane (to me), but swapping <t:ToRecipients> and <t:Body> in the <t:Message> element indeed solved the problem.
I did this by swapping the two corresponding setters in my code:
auto message = ews::message();
// First, set properties of the general "item":
message.set_subject("Test mail from outer space");
auto text = ews::body("This is a test.");
message.set_body(text);
// Then, set properties of the concrete "message":
std::vector<ews::mailbox> recipients;
recipients.push_back(ews::mailbox("..."));
message.set_to_recipients(recipients);
I'm not sure if this is a bug in ews-cpp, in EWS / Exchange server, or in the EWS schema definition.
I would like to make request to web service from mule flow. So far I got WSDL generate classes (wsdl2java), prepared flow (below), and "successfully" send request. Now, problem is, that even thou I have taken base class from generated class and put it in payload it does not generate required soap.
My flow:
<flow name="flow1" doc:name="flow1">
<quartz:inbound-endpoint jobName="testingJob" repeatInterval="10810000" repeatCount="0" startDelay="5000" responseTimeout="10000" doc:name="Quartz">
<quartz:event-generator-job groupName="g1job" jobGroupName="g1job">
<quartz:payload>a</quartz:payload>
</quartz:event-generator-job>
</quartz:inbound-endpoint>
<logger message="Starting quartz for testing purpouses" level="INFO" doc:name="Logger"/>
<custom-transformer class="com.example.GenerateSimpleRoutePublish" doc:name="Java"/>
<cxf:simple-client doc:name="SOAP" serviceClass="com.example.ws.MyWebService" operation="send">
</cxf:simple-client>
<logger message="#[payload]" level="INFO" doc:name="Logger"/>
<http:outbound-endpoint exchange-pattern="request-response" host="localhost" port="9094" path="sync-server-web/services/myws" method="POST" connector-ref="http_internal" doc:name="HTTP"/>
</flow>
GenerateSimpleRoutePublish just put base object into payload and move on.
Result that is sent as soap request:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns1:send xmlns:ns1="http://somenamespace.si/">
<ns1:arg0>
<ns1:MyRequest>
...
But it should look like this:
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Body>
<ns1:send xmlns:ns1="http://somenamespace.si/">
<ns1:MyRequest>
...
Notice that is not there anymore in desired xml.
Anyone knows how to achieve that? I did googled a lot but just don't find right solution. If more is required then I can provide info.
Thanks!
EDIT
<?xml version="1.0" encoding="UTF-8"?>
<wsdl:definitions name="MyWebService" targetNamespace="http://ws.example.com/" xmlns:ns1="http://schemas.xmlsoap.org/soap/http" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
xmlns:tns="http://ws.example.com/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<wsdl:types>
<xs:schema elementFormDefault="unqualified" targetNamespace="http://ws.example.com/"
version="1.0" xmlns:tns="http://ws.example.com/" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xs:element name="MyRequest" type="tns:MyRequest" />
<xs:element name="send" type="tns:send" />
<xs:element name="sendResponse" type="tns:sendResponse" />
<xs:complexType name="send">
<xs:sequence>
<xs:element minOccurs="0" ref="tns:MyRequest" />
</xs:sequence>
</xs:complexType>
<xs:complexType final="extension restriction" name="MyRequest">
<xs:complexContent>
...
Transformer class GenerateSimpleRoutePublish.java:
#Override
public MuleEvent process(MuleEvent event) throws MuleException {
event.setMessage(transformMessage(event.getMessage(), event.getEncoding()));
// TODO Auto-generated method stub
return event;
}
public MuleMessage transformMessage(MuleMessage message, String outputEncoding) throws TransformerException {
MyRequest myRequest = new MyRequest();
/**
* some filling of testing data that is formatted correctly when soap is sent.
*/
Send send = new Send();
send.setMSyequest(myRequest);//the only setter method available for Send
message.setPayload(send);
return message;
}
Send.java methods and xml definition:
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "send", propOrder = {"myRequest"})
public MyRequest getMyRequest()
public void setMyRequest(MyRequest value)
Instead of using a custom-transformer you could use Groovy script to send SOAP request to webservice client just as Java pojo class... Please check the reference :- https://m-square.com.au/consuming-net-wcf-soap-web-services-from-mule/
I've generated an XSD from a set of example request files for an XML web service (using Xmplify - but I doubt that's important).
When I run this through gsoap, I get no errors or warnings, but even with -i or -j option on soapcpp2, I get no C++ proxy files generated (eg soapProxy.h).
Only the following files are generated:
ns1.nsmap
request.h
soapC.cpp
soapH.h
soapStub.h
Commands used:
wsdl2h request.xsd
soapcpp2 -i -C -I/usr/local/share/gsoap/import request.h
I figure there is something specific about the XSD required in order to generate these?
How do I get the proxy files generated? I know I can use without proxy objects, but it looks a lot more messy!
Schema doc is included below.
Thanks for any advice!
Phil.
<xs:schema xmlns:xs='http://www.w3.org/2001/XMLSchema' elementFormDefault='unqualified'>
<xs:element name='REQUEST'>
<xs:complexType>
<xs:sequence>
<xs:element ref='USERTOKEN'/>
<xs:element ref='ACTION'/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name='USERTOKEN'>
<xs:complexType>
<xs:sequence>
<xs:element ref='USERKEY'/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name='USERKEY' type='xs:NCName'/>
<xs:element name='ACTION'>
<xs:complexType>
<xs:sequence>
<xs:element minOccurs='0' ref='PARAMETER'/>
</xs:sequence>
<xs:attribute name='NAME' use='required' type='xs:NCName'/>
</xs:complexType>
</xs:element>
<xs:element name='PARAMETER'>
<xs:complexType mixed='true'>
<xs:attribute name='NAME' use='required' type='xs:NCName'/>
</xs:complexType>
</xs:element>
</xs:schema>
The wsdl2h tool does not generate proxy and service code for XSD files, since there are no operations defined in these (only in WSDL). You can use the gSOAP-generated (de)serializers for the XSD root elements to send/recv XML data that is (de)serialized from the C++ data types. For example
#include "ns1.nsmap" // ns1 namespaces etc
struct soap *ctx = soap_new();
ns1__REQUEST r;
r.soap_default(ctx); // reset content
r.USERTOKEN = … // set r's content as needed
ctx.os = … // set the output stream
soap_write_ns1__REQUEST(ctx, &r); // serialize REQUEST
You can send/recv data over streams, sockets, etc.
how can I prevent string argument from beeing parsed as xml ?
<s:element name="MyResponse">
<s:complexType>
<s:sequence>
<s:element type="s:string" name="xmlResultWithStringType" minOccurs="0" maxOccurs="1" />
</s:sequence>
</s:complexType>
</s:element>
in log I have a correct answer -
Hello xmlStart <foo>in foo<bar>in bar</bar> end foo</foo> xmlEnd
full log :
---[HTTP request - http://localhost:8080/mockXXX]---
Accept: application/soap+xml, multipart/related
Content-Type: application/soap+xml; charset=utf-8;action="http://xxx"
User-Agent: JAX-WS RI 2.2.7-b01 svn-revision#13316
<?xml version="1.0" ?><S:Envelope xmlns:S="http://www.w3.org/2003/05/soap-envelope"><S:Body><MyRequest xmlns="http://fff"><xmlRequest>req do webserwisu</xmlRequest></MyRequest></S:Body></S:Envelope>--------------------
---[HTTP response - http://localhost:8080/mockXXX - 200]---
null: HTTP/1.1 200 OK
Content-Type: application/soap+xml;charset=UTF-8
Server: Jetty(6.1.x)
Transfer-Encoding: chunked
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:fff="http://fff">
<soap:Header/>
<soap:Body>
<fff:MyResponse>
<!--Optional:-->
<fff:XmlResultWithStringType>Hello xmlStart <foo>in foo<bar>in bar</bar> end foo</foo> xmlEnd</fff:XmlResultWithStringType>
</fff:MyResponse>
</soap:Body>
</soap:Envelope>--------------------
but webservice call returns only
xmlEnd2
whole beginning is lost, the content of XmlResultWithStringType is parsed by xml parser,
but it should not,
how can I prevent it from beeing parsed ?
I use jax-ws-RI implementation,
it should be but into CDATA section
<![CDATA[ any xml possible here, it won't be treated as xml but as string ]]>
otherwise, without CDATA, it is treated as xml not as string.
I am calling Webservice from adobe process .
my wsdl contains web method "storeDocument" which takes Document as input.
<xs:element name="storeDocument">
<xs:complexType>
<xs:sequence>
<xs:element xmlns:java="java:org.w3c.dom" name="req" type="java:Document"/>
</xs:sequence>
</xs:complexType>
</xs:element>
<xs:element name="storeDocumentResponse">
<xs:complexType>
<xs:sequence>
<xs:element name="return" type="xs:string"/>
</xs:sequence>
</xs:complexType>
</xs:element>
but when i generate request in webservice setting. it shows
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:res="http://resourceusage.resource.domain.services.nyss.ktv.tdc.com" xmlns:java="java:org.w3c.dom">
<soapenv:Header/>
<soapenv:Body>
<res:storeDocument>
<res:req>
<java:XmlStandalone>?</java:XmlStandalone>
<java:XmlVersion>?</java:XmlVersion>
<java:StrictErrorChecking>?</java:StrictErrorChecking>
<java:DocumentURI>?</java:DocumentURI>
</res:req>
</res:storeDocument>
</soapenv:Body>
</soapenv:Envelope>
I dont have idea how to invoke this service , i tried to give
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:res="http://resourceusage.resource.domain.services.nyss.ktv.tdc.com" xmlns:java="java:org.w3c.dom">
<soapenv:Header/>
<soapenv:Body>
<res:storeDocument>
<res:req>
<java:StrictErrorChecking>false</java:StrictErrorChecking>
<java:DocumentURI>{$ /process_data/#outputForm $}</java:DocumentURI>
</res:req>
</res:storeDocument>
</soapenv:Body>
</soapenv:Envelope>
But it is not working
it gives me error
<bea_fault:stacktrace xmlns:bea_fault="http://www.bea.com/servers/wls70/webservice/fault/1.0.0">com.bea.xml.XmlRuntimeException: java.lang.InstantiationException: org.w3c.dom.Document
at com.bea.staxb.runtime.internal.ClassLoadingUtils.newInstance(ClassLoadingUtils.java:137)
at com.bea.staxb.runtime.internal.ByNameRuntimeBindingType.createIntermediary(ByNameRuntimeBindingType.java:207)
at com.bea.staxb.runtime.internal.AttributeUnmarshaller.unmarshal(AttributeUnmarshaller.java:36)
at com.bea.staxb.runtime.internal.UnmarshalResult.unmarshalBindingType(UnmarshalResult.java:174)
at com.bea.staxb.runtime.internal.UnmarshalResult.unmarshalType(UnmarshalResult.java:212)
at com.bea.staxb.runtime.internal.UnmarshallerImpl.unmarshalType(UnmarshallerImpl.java:127)
at weblogic.wsee.bind.runtime.internal.LiteralDeserializerContext.unmarshalType(LiteralDeserializerContext.java:70)
at weblogic.wsee.bind.runtime.internal.BaseDeserializerContext.internalDeserializeType(BaseDeserializerContext.java:170)
at weblogic.wsee.bind.runtime.internal.BaseDeserializerContext.deserializeType(BaseDeserializerContext.java:87)
at weblogic.wsee.bind.runtime.internal.BaseDeserializerContext.deserializeWrappedElement(BaseDeserializerContext.java:133)
at weblogic.wsee.codec.soap11.SoapDecoder.decodePart(SoapDecoder.java:407)
at weblogic.wsee.codec.soap11.SoapDecoder.decodeParams(SoapDecoder.java:245)
at weblogic.wsee.codec.soap11.SoapDecoder.decodeParts(SoapDecoder.java:164)
at weblogic.wsee.codec.soap11.SoapDecoder.decode(SoapDecoder.java:117)
at weblogic.wsee.codec.soap11.SoapCodec.decode(SoapCodec.java:139)
at weblogic.wsee.ws.dispatch.server.CodecHandler.decode(CodecHandler.java:138)
at weblogic.wsee.ws.dispatch.server.CodecHandler.handleRequest(CodecHandler.java:39)
at weblogic.wsee.handler.HandlerIterator.handleRequest(HandlerIterator.java:127)
at weblogic.wsee.ws.dispatch.server.ServerDispatcher.dispatch(ServerDispatcher.java:85)
at weblogic.wsee.ws.WsSkel.invoke(WsSkel.java:80)
at weblogic.wsee.server.servlet.SoapProcessor.handlePost(SoapProcessor.java:66)
at weblogic.wsee.server.servlet.SoapProcessor.process(SoapProcessor.java:44)
at weblogic.wsee.server.servlet.BaseWSServlet$AuthorizedInvoke.run(BaseWSServlet.java:173)
at weblogic.wsee.server.servlet.BaseWSServlet.service(BaseWSServlet.java:92)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:856)
at weblogic.servlet.internal.StubSecurityHelper$ServletServiceAction.run(StubSecurityHelper.java:227)
at weblogic.servlet.internal.StubSecurityHelper.invokeServlet(StubSecurityHelper.java:125)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:283)
at weblogic.servlet.internal.ServletStubImpl.execute(ServletStubImpl.java:175)
at weblogic.servlet.internal.WebAppServletContext$ServletInvocationAction.run(WebAppServletContext.java:3231)
at weblogic.security.acl.internal.AuthenticatedSubject.doAs(AuthenticatedSubject.java:321)
at weblogic.security.service.SecurityManager.runAs(SecurityManager.java:121)
at weblogic.servlet.internal.WebAppServletContext.securedExecute(WebAppServletContext.java:2002)
at weblogic.servlet.internal.WebAppServletContext.execute(WebAppServletContext.java:1908)
at weblogic.servlet.internal.ServletRequestImpl.run(ServletRequestImpl.java:1362)
at weblogic.work.ExecuteThread.execute(ExecuteThread.java:209)
at weblogic.work.ExecuteThread.run(ExecuteThread.java:181)
Caused by: java.lang.InstantiationException: org.w3c.dom.Document
at java.lang.Class.newInstance0(Class.java:335)
at java.lang.Class.newInstance(Class.java:303)
at com.bea.staxb.runtime.internal.ClassLoadingUtils.newInstance(ClassLoadingUtils.java:135)
... 36 more
Caused by: java.lang.InstantiationException: org.w3c.dom.Document
at java.lang.Class.newInstance0(Class.java:335)
at java.lang.Class.newInstance(Class.java:303)
at com.bea.staxb.runtime.internal.ClassLoadingUtils.newInstance(ClassLoadingUtils.java:135)
at com.bea.staxb.runtime.internal.ByNameRuntimeBindingType.createIntermediary(ByNameRuntimeBindingType.java:207)
at com.bea.staxb.runtime.internal.AttributeUnmarshaller.unmarshal(AttributeUnmarshaller.java:36)
at com.bea.staxb.runtime.internal.UnmarshalResult.unmarshalBindingType(UnmarshalResult.java:174)
Please help..
With the LiveCycle Workbench you can use the WebServices Service to invoke other webservices.
On this website lctips.wordpress.com
you can find some examples.
You can also call webservice from the form with javascript or dataconnection.
invoking-a-web-service programmatically