Urgent - Invoking a web service from Javascript Mashup
Hi,
I am very new to WSO2 stack. I was trying the following scenario
1) Created a simple web service and deployed in WSAS. The service simply takes an input string and prints back "hi"+ the input string. I tested it through the WSAS console and is working fine.
I could also generate WSDL 1.1 using the WSAS tool
2) Now want to invoke the WSAS service from a mashup. For that I have created a mashup in the WSO2 mashup server which has the following code
function toString(){
//TODO: Add function code here
// greet operation
var greetReturn = 'initial';
var version = new WSRequest();
var options = new Array();
options.useSOAP = 1.1;
options.useWSA = 1.0;
options.action = "urn:greet";
request = "<greet/>";
try {
version.open(options,"http://10.226.106.68:9762/services/MyService", false); version.send(request);
greetReturn = version.responseE4X;
} catch (e) {
print(e);
}
return greetReturn;
}
When I try invoking this mashup using the Try option, The request is reaching the WSAS server but gives the following error
ROR [2008-03-06 14:28:04,483] Exception occurred while trying to invoke service method greet
g.apache.axis2.AxisFault: namespace mismatch require http://com found none
at org.apache.axis2.rpc.receivers.RPCUtil.invokeServiceClass(RPCUtil.java:172)
at org.apache.axis2.rpc.receivers.RPCMessageReceiver.invokeBusinessLogic(RPCMessageReceiver.java:98)
at org.apache.axis2.receivers.AbstractInOutMessageReceiver.invokeBusinessLogic(AbstractInOutMessageReceiver.java:40)
at org.apache.axis2.receivers.AbstractMessageReceiver.receive(AbstractMessageReceiver.java:96)
at org.apache.axis2.engine.AxisEngine.receive(AxisEngine.java:148)
at org.apache.axis2.transport.http.HTTPTransportUtils.processHTTPPostRequest(HTTPTransportUtils.java:275)
at org.apache.axis2.transport.http.AxisServlet.doPost(AxisServlet.java:121)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:709)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:802)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:252)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.wso2.adminui.AdminUIServletFilter.doFilter(AdminUIServletFilter.java:142)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:202)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:173)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:213)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:178)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:126)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:105)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:107)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:148)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:869)
at org.apache.coyote.http11.Http11BaseProtocol$Http11ConnectionHandler.processConnection(Http11BaseProtocol.java:667)
at org.apache.tomcat.util.net.PoolTcpEndpoint.processSocket(PoolTcpEndpoint.java:527)
at org.apache.tomcat.util.net.LeaderFollowerWorkerThread.runIt(LeaderFollowerWorkerThread.java:80)
at org.apache.tomcat.util.threads.ThreadPool$ControlRunnable.run(ThreadPool.java:684)
at java.lang.Thread.run(Thread.java:595)
What am I doing wrong here?
Find attached the WSDL file generated for the WSAS service.
Please help
Thanks Shency
| Attachment | Size |
|---|---|
| MyService.xml | 4.58 KB |
- Login or register to post comments
- Printer friendly version
- 941 reads











Hi Shency, I see two
Hi Shency,
I see two problems in your request you are making. You get this error because point 1 below, but of u fixed that it would give u another error. This can be fixed by following point 2.
1. You get this error because the namespace of your request does not match the namespace accepted by the service. Let me explain this further. The WSDL genarated by WSAS has describes its schema as follows,
<xs:schema xmlns:ns="http://com" attributeFormDefault="qualified" elementFormDefault="qualified" targetNamespace="http://com">
elementFormDefault="qualified" would mean that all request coming into this service should be namespace qualified. and the targetNamespace states what namespace that should be in. So basically the grrep element should have look like <p:greet xmlns:p="http://com"/>
2. Secondly the payload that your sending does not match the request axpected by the grret operation. The schema for the input of the grret operation is
<xs:element name="greet">
<xs:complexType>
<xs:sequence>
<xs:element minOccurs="0" name="say" nillable="true" type="xs:string" />
</xs:sequence>
</xs:complexType>
</xs:element>
hence the payload should look like,
<p:greet xmlns:p="http://com">
<say>Hi there</say>
</p:greet>
You are missing the say element in there. (Well as its really optional in the schema you dont really need it, but it looks like your service expects this parameter.)
So thats how you will get this scenario to work. But let me advice you on how you can make this even simple. Leave it to us to formulate how your payload should look and use a javaScript stub for this service.
Here are the steps.
1. Goto the stub genarator tool in the Mashup Server which is at https://localhost:7443/stub_gen.jsp
2. Give the URL (or you can even upload the WSDL you have attached here) of the WSDL and choose E4X stub and get a stub genarated.
3. Copy the content of the stub and drop it into a file in the your resources folder. Assuming you named it MyService.stub and that the Mashup you are writing is foo.js this stub should go into foo.resources.
4. Now your Mashup can include this stub and call the external service as follows (foo.js)
system.include("MyService.stub");
function callMyService(){
// greet operation
var greetReturn = 'initial';
try {
greetReturn = MyService.greet("Hi There");
} catch (e) {
print(e);
}
return greetReturn;
}
Its simple as that. Hope you get it going and have fun with the Mashup Server.
Thanks,
Keith.
Hi Keith, I tried this
Hi Keith,
I tried your your above suggestion and I am still unable to invoke the web service through java script stub.
I am attaching the files:
1. foo.js
2. index.html
3. MyService.stub
I get the following error on the console:
WARN [2008-05-02 01:01:17,473] Code has no side effects in file MyService.stub at line 105 column 44 in line : resultValue;
WARN [2008-05-02 01:01:17,488] Code has no side effects in file MyService.stub at line 161 column 44 in line : resultValue;
WARN [2008-05-02 01:01:17,488] Code has no side effects in file MyService.stub at line 249 column 44 in line : resultValue;
WARN [2008-05-02 01:01:17,488] Code has no side effects in file MyService.stub at line 305 column 44 in line : resultValue;
ReferenceError: "MyService" is not defined.
What am I missing?
Thanks,
Kamal
You have used the incorrect service Name
Hi Kamal,
You should be invoking the service as TemperatureConverter.f2cConvertion(80.0);
Although you saved the stub as MyService.stub the stub was genarated for the TemperatureConverter servive. If you take look at the stub it shows you sample usage right at the top.
Thanks,
Keith.
Axis Fault: Transport information error
Hi Keith,
I changed the service name as suggested. I am getting a different error as below:
org.apache.axis2.AxisFault: The system cannot infer the transport information from the TemperatureConverter URL.
I added some print statements in the stub and here's what I found:
this._options is blank
this._endpointDetails[this.endpoint].address is TemperatureConverter
isAysnc is false
The above three arguments are passed to thisRequest.open(this._options, details.address, isAsync) method and it returns successfully.
The next statement is a send operation where it fails and gives the above error. Here's the method from the stub
thisRequest.send(reqContent);
value of reqContent is <p:f2cConvertion xmlns:p="http://example.ws"><fValue xmlns="http://example.ws">80</fValue></p:f2cConvertion>
Please let us know what is going wrong here.
Also, I didn't find the stub referring to the actual endpoint location (or the server address) where the TemperatureConverter service is deployed.
So, I am not sure how it will invoke the remote service. Shouldn't the stub have that information from the wsdl? I saw the wsdl has the information. Please advise.
I am attaching wsdl for your reference.
Thanks,
Kamal
Its a axis2 bug thats already fixed Here is a workaround
Hi Kamal,
This is a bug that was in axis2. We have fixed this already in the trunk and hence is available in the nightly build. As a workaround for the release that you r using you will have to modify the stub. Relace
This worked but...
Hi Keith,
Thanks for the suggestions. The change in the endpoint worked and now I am getting the response XML from the webservice as below:
<ns:f2cConvertionResponse xmlns:ns="http://example.ws"><ns:return>30.0</ns:return></ns:f2cConvertionResponse>
However, Line 159 of the stub which is as below doesn't return the extracted value. I printed it on the console and it prints blank.
var extractedValue = (response["return"]).toString();
Can you please tell me what's missing here?
Also, I have a general question regarding parsing the xml response. After, we get the response in E4X through request.responseE4X, how do we get to the value in the XML?
We tried to follow the example in the currency converter posted on the mooshup website, but it's not working for us. Maybe, we are missing something. We would like to be independent
of the browser with our XML parsing. Is the answer an independent XML translation service? Please let us know your recommendations on that too.
Thanks,
Kamal
Looks like a bug...
This looks like a bug I recently fixed in the stub (https://wso2.org/jira/browse/MASHUP-745). The stub was not correctly handling namespaces in elementformdefault="qualified" schemas for the e4x dialect.
I have had great success with using the 1.0.2 release with the nightly stubs, so you may find just copying the files below to your /lib directory will solve the problem until the next release:
https://wso2.org/repos/wso2/trunk/commons/dynamic-codegen/src/jsstub.xslt
https://wso2.org/repos/wso2/trunk/commons/dynamic-codegen/src/wsdl2sig.xslt
https://wso2.org/repos/wso2/trunk/commons/dynamic-codegen/src/tryit.xslt
Regarding getting values out of XML in E4X, take a look at the E4X Quick Start guide in the Mashup Server documentation: http://wso2.org/project/mashup/1.0.2/docs/e4xquickstart.html. Mostly navigating the XML is done as if element children were properties (doc.element1.element2), but there are a number of reserved words in Javascript (like "return" in the line from the stub you give) that require an escaping syntax. If you have trouble post a snippet of the XML and we'll show you an example expression to extract the value.
Thanks for the questions!
Jonathan
xslt didn't change the result
Hi Jon,
I downloaded the xslt files in the lib folder and renamed the existing xslt files as .old files. After restarting the server, I tried running it again, but it still get the extractedValue as blank. Then I tried changing the statement from
var extractedValue = (response["return"]).toString();
to
var extractedValue = (response["ns:return"]).toString();
on line 159 of my stub. I am not sure if this was required or if this is the correct way to do this. But, I still tried it but without any change in the result.
Also, it would be helpful to have an example to parse the XML with the keyword return. The response xml is as below:
<ns:f2cConvertionResponse xmlns:ns="http://example.ws"><ns:return>26.666666666666668</ns:return></ns:f2cConvertionResponse>
I have built another js file using WSRequest where I capture the above response in the variable as below:
response = wsrequest.responseE4X;
Then I create a namespace variable as below:
var ws = new Namespace("http://example.ws");
I am trying to figure out how to get the text with the ns:return above from the above xml for the example using WSRequest object.
Thanks,
Kamal
Extracting the value.
The responseE4X property corresponds to the f2cConversionResponse element. Normally you can extract a child element from such an XML element like this:
var response = response.responseE4X.return;
But in this case there are a few twists - first is the namespace:
var ws = new Namespace("http://example.ws");
var response = response.responseE4X.ws::return;
But "return" is a reserved word in Javascript, so we have to get even trickier:
var ws = new Namespace("http://example.ws");
var response = response.responseE4X.ws::["return"];
That one took quite a deep read of the pseudo-code in the E4X spec to figure out! The trickiest E4X statement I'd come across... At this point we've isolated the return element(s), and since we know there's only one child and it doesn't have any other children we can just convert it to a string using .toString():
var ws = new Namespace("http://example.ws");
var response = response.responseE4X.ws::["return"].toString();
This fix is in the stub, not sure why it's not working for you. I'll investigate a bit further on a 1.0.2 install.
parse worked for WSRequest approach
Hi Jon,
The parse approach for the XML response with a keyword "return" worked as per your suggestions above. Thanks for that.
Please let me know what you find with the javascript stub issue.
Thanks for all the help!
Kamal