I'm working on custom axis2 module for wso2 esb. Right now I'm using code from https://docs.wso2.com/display/ESB490/Writing+an+Axis2+Module
and I have a problem with incoming requests. It doesn't matter what request I send because it always looks like this:
<?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"><soapenv:Body/></soapenv:Envelope>
On the other hand OutFlow works more or less as it should - response looks ok but instead of "out" its direction is set as "in". If I'm not mistaken invoke method will be called for requests and revoke for responses - am I right? In my case both are using invoke. Any ideas what I'm doing wrong?
Edit:
My handler code:
public class LogHandler extends AbstractHandler implements Handler {
private Logger log = Logger.getLogger(LogHandler.class.toString());
#Override
public void init(HandlerDescription handlerDescription) {
super.init(handlerDescription);
}
public InvocationResponse invoke(MessageContext msgContext) throws AxisFault {
System.out.println("invoked: " + msgContext.getEnvelope().toString() + "\n");
log.info("invoked: " + msgContext.getEnvelope().toString() + "\n");
return InvocationResponse.CONTINUE;
}
public void revoke(MessageContext msgContext) {
log.info("revoked: " + msgContext.getEnvelope().toString() + "\n");
}
}
Module:
public class LoggingModule implements Module {
private static final Log log = LogFactory.getLog(LoggingModule.class);
// initialize the module
public void init(ConfigurationContext configContext, AxisModule module) throws AxisFault {
}
public void engageNotify(AxisDescription axisDescription) throws AxisFault {
}
// shutdown the module
public void shutdown(ConfigurationContext configurationContext) throws AxisFault {
}
public String[] getPolicyNamespaces() {
return null;
}
public void applyPolicy(Policy policy, AxisDescription axisDescription) throws AxisFault {
}
public boolean canSupportAssertion(Assertion assertion) {
return true;
}
}
module.xml:
<module name="sample-logging" class="pl.wso2.logging.LoggingModule">
<InFlow>
<handler name="InFlowLogHandler" class="pl.wso2.logging.LogHandler">
<order phase="loggingPhase"/>
</handler>
</InFlow>
<OutFlow>
<handler name="OutFlowLogHandler" class="pl.wso2.logging.LogHandler">
<order phase="loggingPhase"/>
</handler>
</OutFlow>
</module>
In my wso2 proxy I use Payload Mediator to create response and then return it using Respond Mediator.
For given request:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<aa>blahblah</aa>
</soapenv:Body>
</soapenv:Envelope>
there two thing logged:
request from InFlow
invoked: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlso
ap.org/soap/envelope/"><soapenv:Body/></soapenv:Envelope>
and response from OutFlow
invoked: <?xml version='1.0' encoding='utf-8'?><soapenv:Envelope xmlns:soapenv="http://schemas.xmlso
ap.org/soap/envelope/"><soapenv:Body><m:checkpriceresponse xmlns:m="http://services.samples/xsd"><m:
code>dsadsa</m:code></m:checkpriceresponse></soapenv:Body></soapenv:Envelope>
As per https://axis.apache.org/axis2/java/core/docs/modules.html#Step2_:_LogHandler ...
"public void invoke(MessageContext ctx);" is the method that is called
by the Axis2 engine when the control is passed to the handler. "public
void revoke(MessageContext ctx);" is called when the handlers are
revoked by the Axis2 engine."
which means since you are calling same handler in both InFlow and OutFlow the same invoke() method should be getting triggered for both the request and the response. If you want different logics to be executed for requests and responses maybe you should write separate handlers for request and response.
After debugging everything I've found that while request was parsed in InFlow, instead of using its soap message, new one (empty) was created. Thankfully it's possible to access proper request using soap tracer handler (or just its code).
Related
I'm invoking a web service that requires WS-Addressing SOAP headers. I'm using Apache Camel with CXF to invoke the web service. When I configure the CXF endpoint with the web service's WSDL, it's smart enough to automatically add WS-Adressing SOAP headers, but I need to set a custom MessageId.
Here is the message that is currently being sent:
<soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope">
<soap:Header>
<ws:international xmlns:ws="http://www.w3.org/2005/09/ws-i18n">
<ws:locale xmlns:ws="http://www.w3.org/2005/09/ws-i18n">en_CA</ws:locale>
</ws:international>
<fram:user wsa:IsReferenceParameter="true" xmlns:fram="http://wsbo.webservice.ephs.pdc.ibm.com/Framework/" xmlns:wsa="http://www.w3.org/2005/08/addressing">BESTSystem</fram:user>
<Action soap:mustUnderstand="true" xmlns="http://www.w3.org/2005/08/addressing">http://webservice.ephs.pdc.ibm.com/Client/QueryHumanSubjects</Action>
<MessageID soap:mustUnderstand="true" xmlns="http://www.w3.org/2005/08/addressing">urn:uuid:945cfd10-9fd2-48f9-80b4-ac1b9f3293c6</MessageID>
<To soap:mustUnderstand="true" xmlns="http://www.w3.org/2005/08/addressing">https://panweb5.panorama.gov.bc.ca:8081/ClientWebServicesWeb/ClientProvider</To>
<ReplyTo soap:mustUnderstand="true" xmlns="http://www.w3.org/2005/08/addressing">
<Address>http://www.w3.org/2005/08/addressing/anonymous</Address>
</ReplyTo>
</soap:Header>
<soap:Body>
<ns2:queryHumanSubjectsRequest xmlns:ns2="http://wsbo.webservice.ephs.pdc.ibm.com/Client/" xmlns:ns3="http://wsbo.webservice.ephs.pdc.ibm.com/FamilyHealth/">
<!-- stuff -->
</ns2:queryHumanSubjectsRequest>
</soap:Body>
</soap:Envelope>
As you can see, the MessageId value is "urn:uuid:945cfd10-9fd2-48f9-80b4-ac1b9f3293c6". I need to set a custom value.
I tried adding the MessageId header they way I add the other headers like "international" and "user", but some part of the framework overrides the value.
// Note this doesn't work! Something overrides the value. It works for other headers.
#Override
public void process(Exchange exchange) throws Exception {
Message in = exchange.getIn();
List<SoapHeader> headers = CastUtils.cast((List<?>) in.getHeader(Header.HEADER_LIST));
SOAPFactory sf = SOAPFactory.newInstance(SOAPConstants.SOAP_1_2_PROTOCOL);
QName MESSAGE_ID_HEADER = new QName("http://www.w3.org/2005/08/addressing", "MessageID", "wsa");
SOAPElement messageId = sf.createElement(MESSAGE_ID_HEADER);
messageId.setTextContent("customValue");
SoapHeader soapHeader = new SoapHeader(MESSAGE_ID_HEADER, messageId);
headers.add(soapHeader);
}
The CXF website has some documentation on how to set WS-Addressing headers, but I don't see how to apply it to Apache Camel. The Apache Camel CXF documentation doesn't specifically mention WS-Addressing either.
The documentation links you posted actually do have the information you need, although it's not immediately obvious how to apply it to Camel.
The CXF documentation says that:
The CXF org.apache.cxf.ws.addressing.impl.AddressingPropertiesImpl object can be used to control many aspects of WS-Addressing including the Reply-To:
AddressingProperties maps = new AddressingPropertiesImpl();
EndpointReferenceType ref = new EndpointReferenceType();
AttributedURIType add = new AttributedURIType();
add.setValue("http://localhost:9090/decoupled_endpoint");
ref.setAddress(add);
maps.setReplyTo(ref);
maps.setFaultTo(ref);
((BindingProvider)port).getRequestContext()
.put("javax.xml.ws.addressing.context", maps);
Note that it sets the addressing properties on the "RequestContext".
The Apache Camel documentation says that:
How to propagate a camel-cxf endpoint’s request and response context
CXF client API provides a way to invoke the operation with request and response context. If you are using a camel-cxf endpoint producer to invoke the outside web service, you can set the request context and get response context with the following code:
CxfExchange exchange = (CxfExchange)template.send(getJaxwsEndpointUri(), new Processor() {
public void process(final Exchange exchange) {
final List<String> params = new ArrayList<String>();
params.add(TEST_MESSAGE);
// Set the request context to the inMessage
Map<String, Object> requestContext = new HashMap<String, Object>();
requestContext.put(BindingProvider.ENDPOINT_ADDRESS_PROPERTY, JAXWS_SERVER_ADDRESS);
exchange.getIn().setBody(params);
exchange.getIn().setHeader(Client.REQUEST_CONTEXT , requestContext);
exchange.getIn().setHeader(CxfConstants.OPERATION_NAME, GREET_ME_OPERATION);
}
});
The above example has some stuff we don't need, but the important thing is that it shows us how to set the CXF Request Context.
Put them together and you get:
#Override
public void process(Exchange exchange) throws Exception {
AttributedURIType messageIDAttr = new AttributedURIType();
messageIDAttr.setValue("customValue");
AddressingProperties maps = new AddressingProperties();
maps.setMessageID(messageIDAttr);
Map<String, Object> requestContext = new HashMap<>();
requestContext.put(JAXWSAConstants.CLIENT_ADDRESSING_PROPERTIES, maps);
exchange.getIn().setHeader(Client.REQUEST_CONTEXT, requestContext);
}
// org.apache.cxf.ws.addressing.JAXWSAConstants.CLIENT_ADDRESSING_PROPERTIES = "javax.xml.ws.addressing.context"
// org.apache.cxf.endpoint.Client.REQUEST_CONTEXT = "RequestContext"
Warning: In my route, I invoke multiple different web services sequentially. I discovered that after setting the RequestContext as shown above, Camel started using the same RequestContext for all web services, which resulted in an error: "A header representing a Message Addressing Property is not valid and the message cannot be processed". This is because the incorrect "Action" header was used for all web service invocations after the first.
I traced this back to Apache Camel using a "RequestContext" Exchange property, separate from the header we set, which apparently takes priority over the header. If I remove this property prior to calling subsequent web services, CXF automatically fills in the correct Action header.
if your problem not solved, I suggest you to combine your cxf service with custom interceptor. it easy to work with your soap message. like this:
<bean id="TAXWSS4JOutInterceptorBean" name="TAXWSS4JOutInterceptorBean" class="com.javainuse.beans.SetDetailAnswerInterceptor " />
<cxf:cxfEndpoint id="CXFTest" address="/javainuse/learn"
endpointName="a:SOATestEndpoint" serviceName="a:SOATestEndpointService"
serviceClass="com.javainuse.SOATestEndpoint"
xmlns:a ="http://javainuse.com">
<cxf:binding>
<soap:soapBinding mtomEnabled="false" version="1.2" />
</cxf:binding>
<cxf:features>
<wsa:addressing xmlns:wsa="http://cxf.apache.org/ws/addressing"/>
</cxf:features>
<cxf:inInterceptors>
<ref bean="TAXWSS4JInInterceptorBean" />
</cxf:inInterceptors>
<cxf:inFaultInterceptors>
</cxf:inFaultInterceptors>
<cxf:outInterceptors>
<ref bean="TAXWSS4JOutInterceptorBean" />
</cxf:outInterceptors>
<cxf:outFaultInterceptors>
</cxf:outFaultInterceptors>
</cxf:cxfEndpoint>
and in the interceptor you can set soap headers like this:
public class SetDetailAnswerInterceptor extends WSS4JOutInterceptor {
public SetDetailAnswerInterceptor() {
}
#Override
public void handleMessage(SoapMessage mc) {
AttributedURIType value = new AttributedURIType();
value.setValue("test");
((AddressingProperties) mc.get("javax.xml.ws.addressing.context.outbound")).setMessageID(value);
}
}
The web service that calls us expects us to return the following XML:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:loc="http://www.csapi.org/schema/parlayx/sms/notification/v2_2/local">
<soapenv:Header />
<soapenv:Body>
<loc:notifySmsDeliveryReceiptResponse />
</soapenv:Body>
</soapenv:Envelope>
We use JAX-WS to provide our web service. The following is how we define our web service interface:
#BindingType(value = javax.xml.ws.soap.SOAPBinding.SOAP11HTTP_MTOM_BINDING)
#WebService (targetNamespace = "http://www.csapi.org/schema/parlayx/sms/notification/v2_2/local")
#HandlerChain(file = "deliverysoaphandler.xml")
#SOAPBinding(style = Style.DOCUMENT)
public interface DeliveryService {
#WebMethod ()
public void notifySmsReception(
#WebParam(name = "correlator", targetNamespace = "http://www.csapi.org/schema/parlayx/sms/notification/v2_2/local") #XmlElement(required = true) String correlator,
#WebParam(name = "message", targetNamespace = "http://www.csapi.org/schema/parlayx/sms/notification/v2_2/local") #XmlElement(required = true) Message message
) throws DeliveryException;
}
This produces the following return document:
<S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/" xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<S:Body>
<ns2:notifySmsReceptionResponse xmlns:ns2="http://www.csapi.org/schema/parlayx/sms/notification/v2_2/local"/>
</S:Body>
</S:Envelope>
We think the document is essential the same as what the calling system expects but gets rejected because 1) the namespaces are capitalized, 2) the same namespace reference is repeated and 3) there is a namespace declaration in the middle of the document.
Is there anyway in which I can persuade the JAX-WS provider to produce what the other system wants?
Based on this description, I am not sure the namespaces are the problem.
The service consumer is expecting:
<soapenv:Body>
<loc:notifySmsDeliveryReceiptResponse />
</soapenv:Body>
but is receiving
<S:Body>
<ns2:notifySmsReceptionResponse xmlns:ns2="..."/>
</S:Body>
which indicates a response to a different operation name.
Try changing your service endpoint interface WebMethod method name to:
#WebMethod ()
public void notifySmsDeliveryReceipt(
Doing so will require you to also change the method name on the implementation class (or it will no longer compile).
Alternatively, you can also just change your #WebMethod to the desired/indicated operation name:
#WebMethod (operationName="notifySmsDeliveryReceipt")
public void notifySmsReception(
The service should now produce:
<S:Body>
<ns2:notifySmsDeliveryReceiptResponse xmlns:ns2="http://www.csapi.org/schema/parlayx/sms/notification/v2_2/local"/>
</S:Body>
I am working a web service using Spring WS. I get the...
WSS0258: More Receiver requirements specified than present in the message
...for a Consumer call as shown below with a X509 Certificate (issued from a central system Desmon).
I do not have much experience working with WS-Security. Therefore need some help to set my security policy file and further hints.
I would really appreciate any hints/help.
Consumer Call
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://app.sample.com/customermanagement/btc/service" xmlns:acc="http://app.sample.com/customermanagement/btc/schema/accountslinkingobject">
<soapenv:Header xmlns:header="http://com.sample.app.japi">
<header:ApplicationID>XX</header:ApplicationID>
<header:CallID>XX1</header:CallID>
<wsse:Security soapenv:actor="http://schemas.xmlsoap.org/soap/actor/next" xmlns:wsse="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd">
<wsse:BinarySecurityToken EncodingType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary" ValueType="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-x509-token-profile-1.0#X509v3" wsu:Id="DESMONCertificate" xmlns:wsu="http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd">REMOVED MORA THAN 2000 BYTES OF CERTIFICATE CONTENT</wsse:BinarySecurityToken>
</wsse:Security>
</soapenv:Header>
<soapenv:Body>.......</soapenv:Body>
</soapenv:Envelope>
And this is my security policy file and interceptors:
Security File
<xwss:SecurityConfiguration xmlns:xwss="http://java.sun.com/xml/ns/xwss/config" dumpMessages="true">
<xwss:RequireSignature requireTimestamp="false">
<xwss:X509Token keyReferenceType="Direct" />
</xwss:RequireSignature>
</xwss:SecurityConfiguration>
Java code from Spring Configuration file
#Bean
public XwsSecurityInterceptor securityInterceptor() {
XwsSecurityInterceptor result = new XwsSecurityInterceptor();
result.setCallbackHandler(callbackHandler());
result.setPolicyConfiguration(new ClassPathResource("security-policy.xml"));
return result;
}
#Bean SpringCertificateValidationCallbackHandler callbackHandler() {
SpringCertificateValidationCallbackHandler handler = new SpringCertificateValidationCallbackHandler();
handler.setAuthenticationManager(authenticationManager());
return handler;
}
#Bean
public ProviderManager authenticationManager() {
ProviderManager pm = new ProviderManager(providers());
return pm;
}
#Bean
public List<AuthenticationProvider> providers() {
X509AuthenticationProvider provider = new X509AuthenticationProvider();
provider.setX509AuthoritiesPopulator(new X509AuthoritiesPopulator() {
#Override
public UserDetails getUserDetails(X509Certificate cert) throws AuthenticationException {
log.info("Got a Certificate: "+cert.toString());
return null;
}
});
List<AuthenticationProvider> list = new ArrayList<AuthenticationProvider>();
list.add(provider);
return list;
}
Thanks a lot in advance!
I'm trying to create an inbound gateway for a SOAP service, that accepts SOAP requests like the following:
<?xml version="1.0" ?><S:Envelope xmlns:S="http://schemas.xmlsoap.org/soap/envelope/">
<S:Header>
<RequestHeader xmlns="http://test.com/">
<SecurityToken>mytoken</SecurityToken>
<RequestID>1234</RequestID>
</RequestHeader>
</S:Header>
<S:Body>
<BaseRequest xmlns="http://test.com/">
<RequestData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:type="BalanceRequest">
<CustomerID>1234</CustomerID>
</RequestData>
</BaseRequest>
</S:Body>
</S:Envelope>
I want to use JAXB for marshalling/unmarshalling the request/response. I have managed to configure Spring/Spring-integration with the following:
<oxm:jaxb2-marshaller id="soapMarshaller" context-path="com.test" />
<int:channel id="soap-channel"/>
<int-ws:inbound-gateway id="ws-inbound-gateway"
request-channel="soap-channel"
marshaller="soapMarshaller"/>
<int:service-activator input-channel="soap-channel">
<bean class="com.test.SoapServiceActivator"/>
</int:service-activator>
And I have tried to extract the SOAP header and body in the service activator.
#ServiceActivator
public BaseResponse issueResponseFor(BaseRequest body,
#Headers Map<String, Object> headerMap) {
return null;
}
BaseRequest is a JAXB annotated class.
#XmlAccessorType(XmlAccessType.FIELD)
#XmlType(name = "", propOrder = {
"requestData"
})
#XmlRootElement(name = "BaseRequest")
public class BaseRequest {
#XmlElement(name = "RequestData")
protected BaseRequestBody requestData;
}
My problem is that in the variable body, I get the body of the SOAP request, but I didn't find anyway to extract the headers of the SOAP request. The headerMap variable holds only the standard Spring-Integration headers (replyChannel, errorChannel, id, timestamp). By headers, I mean the SecurityToken+RequestID, and also the HTTP header with the name of the requested action.
Any idea how to do that ?
Try to use mapped-request-headers="*".
By default the the DefaultSoapHeaderMapper maps only standard headers. And in this case it is only WebServiceHeaders.SOAP_ACTION
UPDATE
Quoting Omar :-)
Thanks ! The following code is working great :
#Autowired
#Qualifier("soapMarshaller")
Jaxb2Marshaller marshaller;
#ServiceActivator
public BaseResponse issueResponseFor(BaseRequest request, #Header("RequestHeader") SoapHeaderElement soapHeader) {
BaseRequestHeader requestHeader = (BaseRequestHeader) JAXBIntrospector.getValue(marshaller.unmarshal(soapHeader.getSource()));`
I just want to call a web service from PL/SQL, so I create a web service :
http://localhost:64955/Service1.asmx?op=add
firstly, the web methods are very simple,like below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Services;
namespace Calculator
{
/// <summary>
/// Summary description for Service1
/// </summary>
[WebService(Namespace = "http://tempuri.org/")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.ComponentModel.ToolboxItem(false)]
// To allow this Web Service to be called from script, using ASP.NET AJAX, uncomment the following line.
// [System.Web.Script.Services.ScriptService]
public class Service1 : System.Web.Services.WebService
{
[WebMethod]
public string HelloWorld()
{
return "Hello World";
}
[WebMethod]
public int add(int firstNum, int secondNum)
{
return firstNum + secondNum;
}
}
}
and I want to invoke the second method(add) in the web service, so I write my PL/SQL code like this:
declare
l_param_list varchar2(512);
l_http_request UTL_HTTP.req;
l_http_response UTL_HTTP.resp;
l_response_text varchar2(32000);
begin
-- service's input parameters
l_param_list := 'firstNum=1'||'&'||'secondNum=2';
--http://localhost:64955/Service1.asmx?op=add
--16.158.161.7
-- prepareint Request...
l_http_request := UTL_HTTP.begin_request ('http://localhost:64955/Service1.asmx?op=add'
,'POST'
,'HTTP/1.1');
--...set header's attributes
UTL_HTTP.set_header(l_http_request,'Content-Type', 'application/x-www-form-urlencoded');
UTL_HTTP.set_header(l_http_request,'Content-Length', length(l_param_list));
--...set input parameters
UTL_HTTP.write_text(l_http_request, l_param_list);
-- get response and obtain received value
l_http_response := UTL_HTTP.get_response(l_http_request);
UTL_HTTP.read_text(l_http_response, l_response_text);
dbms_output.put_line(l_response_text);
dbms_output.put_line('test1');
--finalizing
UTL_HTTP.end_response(l_http_response);
exception
when UTL_HTTP.end_of_body then
UTL_HTTP.end_response(l_http_response);
dbms_output.put_line('test2');
end;
But when I run this PL/SQL code segment, I got some exceptions:
<?xml version="1.0" encoding="utf-8"?><soap:Envelope xmlns:soap="http://www.w3.org/2003/05/soap-envelope" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"><soap:Body><soap:Fault><soap:Code><soap:Value>soap:Receiver</soap:Value></soap:Code><soap:Reason><soap:Text xml:lang="en">System.Web.Services.Protocols.SoapException: Server was unable to process request. ---> System.Xml.XmlException: Root element is missing.
at System.Xml.XmlTextReaderImpl.Throw(Exception e)
at System.Xml.XmlTextReaderImpl.ThrowWithoutLineInfo(String res)
at System.Xml.XmlTextReaderImpl.ParseDocumentContent()
at System.Xml.XmlTextReaderImpl.Read()
at System.Xml.XmlTextReader.Read()
at System.Web.Services.Protocols.SoapServerProtocol.SoapEnvelopeReader.Read()
at System.Xml.XmlReader.MoveToContent()
at System.Web.Services.Protocols.SoapServerProtocol.SoapEnvelopeReader.MoveToContent()
at System.Web.Services.Protocols.SoapServerProtocolHelper.GetRequestElement()
at System.Web.Services.Protocols.Soap12ServerProtocolHelper.RouteRequest()
at System.Web.Services.Protocols.SoapServerProtocol.RouteRequest(SoapServerMessage message)
at System.Web.Services.Protocols.SoapServerProtocol.Initialize()
at System.Web.Services.Protocols.ServerProtocol.SetContext(Type type, HttpContext context, HttpRequest request, HttpResponse response)
at System.Web.Services.Protocols.ServerProtocolFactory.Create(Type type, HttpContext context, HttpRequest request, HttpResponse response, Boolean& abortProcessing)
--- End of inner exception stack trace ---</soap:Text></soap:Reason><soap:Detail /></soap:Fault></soap:Body></soap:Envelope>
test1
I am a beginner on the PL/SQL, so can anybody tell me what's wrong with my code?
BTW, the web service can be invoked normally from a windows form application.
The problem is that your webservice is SOAP , but you are not sending a SOAP request.
To do this, check the wsdl of your webservice, by browsing this URL http://localhost:64955/Service1.asmx?wsdl ,from there you will know how to create the SOAP envelop to call your webmethod.
you would do something like :
soap_request :=
'<SOAP-ENV:Envelope
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<SOAP-ENV:Body>
<m:add xmlns:m="Some-URI">
<firstNum>1</firstNum>
<secondNum>2</secondNum>
</m:add>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>';
l_http_request := UTL_HTTP.begin_request ('http://localhost:64955/Service1.asmx?op=add'
,'POST'
,'HTTP/1.1');
--...set header's attributes
UTL_HTTP.set_header(l_http_request,'Content-Type', 'application/xml');
UTL_HTTP.set_header(l_http_request,'Content-Length', length(soap_request));
--...set input parameters
UTL_HTTP.write_text(l_http_request, soap_request);
-- get response and obtain received value
l_http_response := UTL_HTTP.get_response(l_http_request);
UTL_HTTP.read_text(l_http_response, l_response_text);
dbms_output.put_line(l_response_text);
dbms_output.put_line('test1');
--finalizing
UTL_HTTP.end_response(l_http_response);