I am getting the below exception when trying to call service from SOAPUI that is fine
because message part element dose not exits in wsdl.
But I want to handle in proper way in CXF web service and send proper fault string instead of below message ex: "Bad Request"
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/">
<soap:Header>
<Action xmlns="http://www.w3.org/2005/08/addressing"/>
<MessageID xmlns="http://www.w3.org/2005/08/addressing">urn:uuid:109a84f4-373d-4406-9087-82bd58bea394</MessageID>
<To xmlns="http://www.w3.org/2005/08/addressing">http://www.w3.org/2005/08/addressing/anonymous</To>
<RelatesTo xmlns="http://www.w3.org/2005/08/addressing">uuid:3dcf9e26-20fc-4c93-bc01-8ca9ab1ae2eb</RelatesTo>
</soap:Header>
<soap:Body>
<soap:Fault>
<faultcode>soap:Client</faultcode>
<faultstring>Message part Reservation was not recognized. (Does it exist in service WSDL?)</faultstring>
</soap:Fault>
</soap:Body>
</soap:Envelope>
Does any one know in cxf where I can handle in proper way ?
You can solve this problem by consuming the web service from a client application. Everywhere you need to consume the WS, should put a BindingProvider to the port. This example is a method of:
...
import javax.xml.ws.BindingProvider;
public class WSClient {
public String getUserName(int userCode) {
WebServiceAuth ss = new WebServiceAuth();
IWebServiceAuth port = ss.getPort(IWebServiceAuth.class);
BindingProvider bindingProvider = (BindingProvider) port;
bindingProvider
.getRequestContext()
.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY,
"http://localhost:8081/WebServiceAuth/WSAuth");
return port.getUserName(userCode);
}
}
In this case you need to put your service's address into the BindingProvider.
Related
I'm using a custom binding in my service and client which basically looks like this:
public class UserNameWsTrustBinding : Binding
{
public override BindingElementCollection CreateBindingElements()
{
var coll = new BindingElementCollection();
coll.Add(CreateSecurityBindingElement());
coll.Add(new TextMessageEncodingBindingElement());
coll.Add(new HttpsTransportBindingElement());
return coll;
}
private SecurityBindingElement CreateSecurityBindingElement()
{
var elem = SecurityBindingElement.CreateUserNameOverTransportBindingElement();
elem.MessageSecurityVersion = MessageSecurityVersion.WSSecurity11WSTrust13WSSecureConversation13WSSecurityPolicy12BasicSecurityProfile10;
return elem;
}
}
This binding works prety well. Except for FaultExceptions which I throw e.g. when validating the user's credentials.
I throw non-generic FaultExceptions like this; nothing special I think:
throw new FaultException(new FaultReason("Blah blah"), new FaultCode("Code42"));
WCF then takes care of putting these faults into a SOAP envelope. The problem is, that there don't get security headers (namely a WS-Security timestamp) baked in:
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
xmlns:a="http://www.w3.org/2005/08/addressing">
<s:Header>
<a:Action s:mustUnderstand="1">http://www.w3.org/2005/08/addressing/soap/fault</a:Action>
<a:RelatesTo>urn:uuid:ff1f54d7-53a0-4650-b967-03a75def5fa4</a:RelatesTo>
</s:Header>
<s:Body>
<s:Fault>
<s:Code>
<s:Value>s:Sender</s:Value>
<s:Subcode><s:Value>Code42</s:Value></s:Subcode>
</s:Code>
<s:Reason><s:Text>Blah blah</s:Text></s:Reason>
</s:Fault>
</s:Body>
</s:Envelope>
When the client application receives this response it complains about it with the following error message:
System.ServiceModel.Security.MessageSecurityException: An unsecured or incorrectly secured fault was received from the other party. See the inner FaultException for the fault code and detail.
This is not surprising, since there is no security header included. I can then get the FaultException from the MessageSecurity's InnerException. It works, but it doesn't feel good.
What is really surprising, however, is that unhandled exceptions that are not caught in my server code get wrapped in a FaultException automatically. And these FaultExceptions have a security header!
<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope" xmlns:a="http://www.w3.org/2005/08/addressing" xmlns:u="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<s:Header>
<a:Action s:mustUnderstand="1">http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher/fault</a:Action>
<a:RelatesTo>urn:uuid:0baffa8b-07ee-4feb-bc44-7e2c7ae85c22</a:RelatesTo>
<o:Security s:mustUnderstand="1" xmlns:o="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<u:Timestamp u:Id="_0">
<u:Created>2022-07-11T13:41:22.007Z</u:Created>
<u:Expires>2022-07-11T13:46:22.007Z</u:Expires>
</u:Timestamp>
</o:Security>
</s:Header>
<s:Body>
<s:Fault>
<s:Code>
<s:Value>s:Receiver</s:Value>
<s:Subcode><s:Value xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:InternalServiceFault</s:Value></s:Subcode>
</s:Code>
<s:Reason><s:Text>The server was unable to process the request due to an internal error. For more information about the error, either turn on IncludeExceptionDetailInFaults (either from ServiceBehaviorAttribute or from the %lt;serviceDebug> configuration behavior) on the server in order to send the exception information back to the client, or turn on tracing as per the Microsoft .NET Framework SDK documentation and inspect the server trace logs.</s:Text></s:Reason>
</s:Fault>
</s:Body>
</s:Envelope>
So, long story short: What am I doing wrong? Or in other words: What do I have to do to make my self-thrown FaultExceptions include a timestamp as well?
i want to consume soap web serivce in apache camel using Java DSL.Any way without CXF.i have already try using CXF with spring.
Here is a simple example that used only camel http without cxf. If you need to perform some modifications of SOAP request string you can just change "constant" to something like "spel".
<setBody><constant><![CDATA[<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<MyAction>
<myparam>ABC</myparam>
</MyAction>
</soapenv:Body>
</soapenv:Envelope>]]></constant></setBody>
<setHeader headerName="SOAPAction"><constant>MySOAPAction</constant></setHeader>
<setHeader headerName="CamelHttpMethod"><constant>POST</constant></setHeader>
<setHeader headerName="Content-Type"><constant>text/xml;charset=UTF-8</constant></setHeader>
<to uri="http://myserver:1234" />
Same with Java DSL
public class MyRouteBuilder extends RouteBuilder {
public void configure() {
from("direct:start")
.setBody(constant("")) // String SOAP content from XML example
.setHeader("SOAPAction", constant("MySOAPAction"))
.setHeader("CamelHttpMethod", constant("POST"))
.setHeader("Content-Type", constant("text/xml;charset=UTF-8"))
.to("http://myserver:1234")
.log("SOAP service called"); // Here you can process service response
}
}
I downloaded the echo sample for mule from internet. I have 1 java class
package org.mule.example.echo;
public class Echo
{
public Echo()
{
}
public String echo(String string)
{
return string;
}
}
And an xml file
<?xml version="1.0" encoding="UTF-8"?>
<mule>
<flow name="EchoFlow">
<inbound-endpoint address=":65082/services/EchoUMO" exchange-pattern="request-response"/>
<cxf:jaxws-service serviceClass="org.mule.example.echo.Echo"/>
<component>
<singleton-object class="org.mule.example.echo.Echo" />
</component>
</flow>
</mule>
When I write :65082/services/EchoUMO in my browser I don't get any good result. In my console i see this error:
WARN 2013-03-04 12:08:10,713 [[sample-echo].connector.http.mule.default.receiver.02] org.apache.cxf.phase.PhaseInterceptorChain: Interceptor for {http://echo.example.mule.org/}EchoService has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: No such operation: (HTTP GET PATH_INFO: /services/EchoUMO)
at org.apache.cxf.interceptor.URIMappingInterceptor.handleMessage(URIMappingInterceptor.java:88)
at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:263)
at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:123)
Can you explain what is going on for me?
When I write :65082/services/EchoUMO in my browser, my browser shows this page:
<soap:Envelope>
<soap:Body><soap:Fault>
<faultcode>soap:Server</faultcode>
<faultstring>No such operation: (HTTP GET PATH_INFO: /services/EchoUMO)</faultstring>
</soap:Fault></soap:Body>
</soap:Envelope>
Your class does not use JAX-WS annotation therefor you get the error.
You have 2 choices:
Keep the current class and use simple service, i.e <cxf:simple-service serviceClass="org.mule.example.echo.Echo"/>
Add JAX-WS annotation to your POJO as explained here
I have a BizTalk 2009 orchestration with a request-response port type that is published as a WCF Basic-HTTP web service. The port has one operation, and that operation has request and response messages with appropriate schemas. After receiving a request on this port, there are a few cases where a fault message should be returned to the client instead of the standard response message. I'm having difficulty getting the correct fault message back to the client. I'd like to be able to set both the faultcode and faultstring elements of the SOAP fault message. Here's what I've tried:
Adding a Fault Message of Type String:
I tried adding a fault message with a message type of string to the operation. Within the orchestration, I constructed a string message and sent it as the response. The fault that was delivered back to the client looked like:
<?xml version="1.0" encoding="utf-8"?>
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<s:Fault>
<faultcode xmlns:a="http://schemas.microsoft.com/net/2005/12/windowscommunicationfoundation/dispatcher">a:InternalServiceFault</faultcode>
<faultstring xml:lang="en-US"><?xml version="1.0" encoding="utf-8"?>
<string>This is the error message.</string></faultstring>
<detail>
<ExceptionDetail xmlns="http://schemas.datacontract.org/2004/07/System.ServiceModel" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<HelpLink i:nil="true"/>
<InnerException i:nil="true"/>
<Message><?xml version="1.0" encoding="utf-8"?>
<string>This is the error message.</string></Message>
<StackTrace>at Microsoft.BizTalk.Adapter.Wcf.Runtime.BizTalkAsyncResult.End() ...</StackTrace>
<Type>Microsoft.BizTalk.Adapter.Wcf.Runtime.BizTalkNackException</Type>
</ExceptionDetail>
</detail>
</s:Fault>
</s:Body>
</s:Envelope>
This almost works, except the faultstring element contains the xml serialized version of my string instead of the string itself. I also cannot set the faultcode element.
Adding a Fault Message of Type http://schemas.xmlsoap.org/soap/envelope/#Fault
I thought I might be able to convince BizTalk to return a fault message along the lines of what I'd expect if I constructed the Fault element and sent that. So I added a fault message with a type of http://schemas.xmlsoap.org/soap/envelope/#Fault, constructed the appropriate message and sent that as the response. The result was the same as above, except instead of a string, the faultstring element contained a CDATA section with the entire xml message I had constructed inside.
So I'm stuck now; I feel like this should be a simple task in BizTalk. The documentation on MSDN, How to Throw Fault Exceptions from Orchestrations Published as WCF Services, tells you nothing about "how" to throw fault exceptions, except that they can be thrown and that you need to set includeExceptionDetailInFaults in the configuration (which I've already done).
Does anyone have any suggestions on how this could be accomplished in BizTalk 2009?
I solved this exact problem by adding a custom WCF IDispatchMessageInspector where i read the reason text from the serialized message and then return a new System.ServiceModel.FaultException message using the deserialized reason text.
In the BizTalk orchestration i use System.String as the PortType fault message-type.
public class HandleUntypedSoapFault : IDispatchMessageInspector
{
public void BeforeSendReply(ref System.ServiceModel.Channels.Message reply, object correlationState)
{
if (reply.IsFault)
{
MessageBuffer buffer = reply.CreateBufferedCopy(int.MaxValue);
MessageFault messageFault = MessageFault.CreateFault(buffer.CreateMessage(), int.MaxValue);
if (!messageFault.HasDetail)
{
reply = buffer.CreateMessage();
return;
}
using (XmlReader reader = XmlReader.Create(new StringReader(messageFault.Reason.ToString())))
{
reader.MoveToContent();
string _faultText = reader.ReadElementContentAsString();
}
reply = Message.CreateMessage(
reply.Version,
new FaultException(
_faultText,
new FaultCode("client")).CreateMessageFault(),
null);
}
}
}
Now the SoapFault will look more like this:
<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
<s:Body>
<s:Fault>
<faultcode>s:Client</faultcode>
<faultstring xml:lang="en-US">An untyped SoapFault from my BizTalk orchestration. This text was set in the orchestration.</faultstring>
</s:Fault>
</s:Body>
</s:Envelope>
Reminded of this long thread I participated in a while back:
http://social.msdn.microsoft.com/forums/en-US/biztalkr2adapters/thread/f69ec7af-a490-4229-81d4-3d1b41bf9c48/
They refer to an SDK sample that might help you, but it's a typed (not un-typed as you requested) fault exception.
I am working with a Silvelright App that consumes a WCF service, I have placed a crossdomain and clientaccesspolicy xml's in the wwwroot of the IIS as well as in the application folder!
yet when the client communicates with the service, it throws an error saying;
An error occurred while trying to make a request to URI ‘http://localhost:1528/MyService.svc’. This could be due to attempting to access a service in a cross-domain way without a proper cross-domain policy in place, or a policy that is unsuitable for SOAP services. You may need to contact the owner of the service to publish a ……
Please help!
Thanks
The clientaccesspolicy.xml needs to be on the same port as your service. It needs to be located at http://localhost:1528/clientaccesspolicy.xml
If you are self hosting the WCF service then you need to host the clientaccesspolicy.xml from within your WCF service. The easiest way I've found to do this is to add a separate service contract that provides an HTTP GET of the clientaccesspolicy.xml.
[ServiceContract()]
public class PolicyRetriever
{
[OperationContract, WebGet(UriTemplate = "/clientaccesspolicy.xml")]
public Stream GetSilverlightPolicy()
{
string result = #"<?xml version=""1.0"" encoding=""utf-8""?>
<access-policy>
<cross-domain-access>
<policy>
<allow-from http-request-headers=""*"">
<domain uri=""*""/>
</allow-from>
<grant-to>
<resource path=""/"" include-subpaths=""true""/>
</grant-to>
</policy>
</cross-domain-access>
</access-policy>";
if (System.ServiceModel.Web.WebOperationContext.Current != null)
{
System.ServiceModel.Web.WebOperationContext.Current.OutgoingResponse.ContentType = "application/xml";
}
return new MemoryStream(Encoding.UTF8.GetBytes(result));
}
}