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
}
}
Related
This question already exists:
How to read/parse soap header request in WCF service created in .Net Core 3.1
Closed 2 years ago.
I need to read SOAP envelope header in ASP.NET WCF service using SoapCore.
This is the soap header example:
<soapenv:Header>
<wsse:Security xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd"
xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">
<wsse:UsernameToken wsu:Id="UsernameToken-5351BA8068B753C930158868612679914">
<wsse:Username>test user</wsse:Username>
<wsse:Password Type="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest">CS++k5OEqKsJByVPPmUqcBkAeoQ=</wsse:Password>
<wsse:Nonce EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary">VK+Ilb/zy80lFbfHAAQupg==</wsse:Nonce>
<wsu:Created>2020-05-05T13:42:06.798Z</wsu:Created>
</wsse:UsernameToken>
</wsse:Security>
</soapenv:Header>
Can anyone help me to parse this soapenv:Header request in .NET Core?
Thanks in advance
There is IMessageinspector interface in SoapCore:
using System.ServiceModel.Channels;
namespace SoapCore.Extensibility
{
public interface IMessageInspector
{
object AfterReceiveRequest(ref Message message);
void BeforeSendReply(ref Message reply, object correlationState);
}
}
You can implement IMessageinspector, and then get the header of the SOAP message in the implementation class.
public class MessageLogger : IMessageInspector
{
public object AfterReceiveRequest(ref Message message)
{
message.Headers.GetHeader<string>(0);
return null;
}
public void BeforeSendReply(ref Message reply, object correlationState)
{
throw new NotImplementedException();
}
}
In my code,it gets the first header of the SOAP message and the header is of type string.
For more information about MessageHeaders,Please refer to the following link:
https://learn.microsoft.com/en-us/dotnet/api/system.servicemodel.channels.messageheaders.getheader?view=dotnet-plat-ext-3.1&viewFallbackFrom=netcore-3.0
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.
I cant find any good samples for that scenario.
Also, the WCF service used the Entity Framework 6.0 which should return big JSON structures.
For now I am just trying to find a simple example which can call a simple WCF service:
[ServiceContract]
public interface ITest
{
[OperationContract(Name = "Test_GetDate")]
[WebGet(UriTemplate = "/GetDate", RequestFormat = WebMessageFormat.Json, ResponseFormat = WebMessageFormat.Json)]
string GetDate();
...
public class Test : ITest
{
public string GetDate()
{
return (DateTime.UtcNow.ToString());
}
...
Thank you
Yes it can. This scenario worked for me, but I was using XML format (WCF SOAP) not rest/json, but You can try.
-I use soap UI to figure out how soap Envelope should look like. This tool is free http://www.soapui.org/ and it is easy to use.
-Create New Soap UI project and paste WSDL address in the input, application will generate empty XML request - soap envelope.
-You can test your service from this app
-I am using cfhttp to invoke service from cf:
We figured out soap envelope and we put this in cf variable :
<cfsavecontent variable="soapBody">
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:tem="http://tempuri.org/" xmlns:ozon="http://schemas.datacontract.org/blah/prc">
<soapenv:Header/>
<soapenv:Body>
<tem:myservicemethod>
<tem:someParameter1>This is my first param</tem:someParameter1>
<tem:someParameter2>
<blah:AC>This is my second parameter</blah:AC>
</tem:someParameter2>
</tem:myservicemethod>
</soapenv:Body>
</soapenv:Envelope>
</cfsavecontent>
Now invoke service. This I digged from Ben Nadel's blog : http://www.bennadel.com/blog/1809-Making-SOAP-Web-Service-Requests-With-ColdFusion-And-CFHTTP.htm
<cfhttp
url="http:/SomeService/Service.svc"
method="post"
result="httpResponse">
<!---
TIP : Look into your WSDL to figure out SOAPAction value
--->
<cfhttpparam
type="header"
name="SOAPAction"
value="http://tempuri.org/SomeService/myservicemethod"
/>
<cfhttpparam
type="header"
name="accept-encoding"
value="no-compression"
/>
<cfhttpparam
type="xml"
value="#trim( soapBody )#"
/>
</cfhttp>
<cfdump var="#httpResponse#" />
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 need help with this question.
I'm using the camel-http component as shown here but I'm having trouble because the body I'm sending has unescaped ampersands. This is causing the query string on the receiving server to break the post into multiple post parameters.
I know I could create compiled routes in java, but I must use the spring xml dialect so that new routes may be create/changed in the config files without a recompile.
So, in short, I'd like to URL Encode the ${body} property on my route using the spring dialect as shown in the (obviously invalid) pseudocode below.
<setBody inheritErrorHandler="true" id="setBody2">
<simple>name=<urlencode>${body}</urlencode></simple>
</setBody>
Ok, I bit the bullet. I created a java POJO
package com.wufoo.camel;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import org.apache.log4j.Logger;
public class PayloadEncoder {
public String getEncodedBody(String body) throws UnsupportedEncodingException {
Logger mylogger = Logger.getLogger("log4j.logger.org.apache.camel");
mylogger.info("Appending payload and URL Encoding");
String encodedBody = new StringBuffer()
.append("payload=")
.append(URLEncoder.encode(body, "UTF-8")).toString();
return encodedBody;
}
}
Then injected it into the context
<bean id="payloadEncoder" class="com.wufoo.camel.PayloadEncoder" />
And finally used a transform to encode the body
<transform>
<method bean="payloadEncoder" method="getEncodedBody"/>
</transform>
That works. If anyone can tell me what's wrong with this approach, please let me know.
You can also use groovy language, like this:
<?xml version="1.0" encoding="UTF-8"?>
<blueprint
xmlns="http://www.osgi.org/xmlns/blueprint/v1.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.osgi.org/xmlns/blueprint/v1.0.0
http://www.osgi.org/xmlns/blueprint/v1.0.0/blueprint.xsd">
<camelContext xmlns="http://camel.apache.org/schema/blueprint">
<route>
<from uri="file:camel/input"/>
<log message="Moving ${file:name} to the output directory"/>
<setBody>
<groovy>
"name=" + URLEncoder.encode(request.getBody(String.class));
</groovy>
</setBody>
<to uri="file:camel/output"/>
</route>
</camelContext>
</blueprint>