Results 1 to 5 of 5
- 09-30-2010, 04:06 PM #1
Member
- Join Date
- Sep 2010
- Posts
- 3
- Rep Power
- 0
multiple response parameters in apache axis are not all not returned
Hi all,
I'm having an issue parsing a soap response message with multiple output
parameters:
An example of the soap response msg (notice it contains 4 sub nodes)
Problem is that the call.getOutputParams method returns a Map with onlyJava Code:<?xml version="1.0" encoding="UTF-8"?> <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi=" http://www.w3.org/2001/XMLSchema-instance"> <soap:Body> <error xmlns="http://testcase/itpserver/wsdl">OK</error> <outKeyValues xmlns="http://testcase/itpserver/wsdl"> <KeyValue> <key>Email</key> <value/> </KeyValue> <KeyValue> <key>Printer</key> <value/> </KeyValue> </outKeyValues> <outDocuments xmlns="http://testcase/itpserver/wsdl"> <Doc> <id>PDF</id> <content>JVBERi0xLjQNJf////8NMSAwIG9iag08PA...</content> </Doc> </outDocuments> <progress xmlns="http://testcase/itpserver/wsdl"/> </soap:Body> </soap:Envelope>
the first node directly under the soap body. I would expect that all 4 the
subnodes are present in the returned Map. (the errorNode is in the Map)
I have looked in to the source of the axis code how that map is filled and
descovered the following:
// call.invoke ==> soapenvelope.getfirstbody ==> body.getfirstboy ==>
getChildren().get(0)!!! (see SOAPBODY.getFirstBody)
==> this confirms the result of my test case
I expected however that the map contains ALL output parameters from the
response body.
Does anybody know what is going on here, why not put all these params in
the Map, or is it a bug???
The test code:
Any feedback is appreciated!Java Code:package client; import java.io.FileOutputStream; import java.io.IOException; import java.net.MalformedURLException; import java.rmi.RemoteException; import java.util.Iterator; import java.util.Map; import java.util.Vector; import javax.xml.rpc.ServiceException; import org.apache.axis.AxisFault; import org.apache.axis.Message; import org.apache.axis.client.Call; import org.apache.axis.client.Service; import org.apache.axis.description.OperationDesc; import org.apache.axis.description.ParameterDesc; import org.apache.axis.utils.XMLUtils; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import client.util.Base64; import com.testcase.www.itpserver.wsdl.ArrayOfDoc; import com.testcase.www.itpserver.wsdl.ArrayOfKeyValue; import com.testcase.www.itpserver.wsdl.ArrayOfString; import com.testcase.www.itpserver.wsdl.Doc; import com.testcase.www.itpserver.wsdl.KeyValue; public class testClient { private static String endPoint = "http://pcwin7:8080/?WSDL"; // private static String endPoint = "http://pcwin7:8082/"; public static void main(String[] args) { try { Service service = new Service(); service.setTypeMappingVersion("1.2"); OperationDesc oper = new org.apache.axis.description.OperationDesc(); oper.setName("SubmitEx"); ParameterDesc param = new org.apache.axis.description.ParameterDesc(new javax.xml.namespace.QName(" http://www.testcase.com/itpserver/wsdl", "service"), org.apache.axis.description.ParameterDesc.IN, new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"), java.lang.String.class, false, false); oper.addParameter(param); param = new org.apache.axis.description.ParameterDesc(new javax.xml.namespace.QName(" http://www.testcase.com/itpserver/wsdl", "parms"), org.apache.axis.description.ParameterDesc.IN, new javax.xml.namespace.QName("http://www.testcase.com/itpserver/wsdl", "ArrayOfString"), com.testcase.www.itpserver.wsdl.ArrayOfString.class, false, false); oper.addParameter(param); param = new org.apache.axis.description.ParameterDesc(new javax.xml.namespace.QName(" http://www.testcase.com/itpserver/wsdl", "inKeyValues"), org.apache.axis.description.ParameterDesc.IN, new javax.xml.namespace.QName("http://www.testcase.com/itpserver/wsdl", "ArrayOfKeyValue"), com.testcase.www.itpserver.wsdl.ArrayOfKeyValue.class, false, false); oper.addParameter(param); param = new org.apache.axis.description.ParameterDesc(new javax.xml.namespace.QName(" http://www.testcase.com/itpserver/wsdl", "inDocuments"), org.apache.axis.description.ParameterDesc.IN, new javax.xml.namespace.QName("http://www.testcase.com/itpserver/wsdl", "ArrayOfDoc"), com.testcase.www.itpserver.wsdl.ArrayOfDoc.class, false, false); oper.addParameter(param); param = new org.apache.axis.description.ParameterDesc(new javax.xml.namespace.QName(" http://www.testcase.com/itpserver/wsdl", "error"), org.apache.axis.description.ParameterDesc.OUT, new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "string"), java.lang.String.class, false, false); oper.addParameter(param); param = new org.apache.axis.description.ParameterDesc(new javax.xml.namespace.QName(" http://www.testcase.com/itpserver/wsdl", "outKeyValues"), org.apache.axis.description.ParameterDesc.OUT, new javax.xml.namespace.QName("http://www.testcase.com/itpserver/wsdl", "ArrayOfKeyValue"), com.testcase.www.itpserver.wsdl.ArrayOfKeyValue.class, false, false); oper.addParameter(param); param = new org.apache.axis.description.ParameterDesc(new javax.xml.namespace.QName(" http://www.testcase.com/itpserver/wsdl", "outDocuments"), org.apache.axis.description.ParameterDesc.OUT, new javax.xml.namespace.QName("http://www.testcase.com/itpserver/wsdl", "ArrayOfDoc"), com.testcase.www.itpserver.wsdl.ArrayOfDoc.class, false, false); oper.addParameter(param); param = new org.apache.axis.description.ParameterDesc(new javax.xml.namespace.QName(" http://www.testcase.com/itpserver/wsdl", "progress"), org.apache.axis.description.ParameterDesc.OUT, new javax.xml.namespace.QName("http://www.testcase.com/itpserver/wsdl", "ArrayOfString"), com.testcase.www.itpserver.wsdl.ArrayOfString.class, false, false); oper.addParameter(param); oper.setReturnType(org.apache.axis.encoding.XMLType.AXIS_VOID); oper.setStyle(org.apache.axis.constants.Style.DOCUMENT); oper.setUse(org.apache.axis.constants.Use.LITERAL); Call call = (Call)service.createCall(); call.setOperation(oper); call.setTargetEndpointAddress( new java.net.URL(endPoint) ); call.setUseSOAPAction(true); call.setSOAPActionURI(" http://www.testcase.com/itpserver/wsdl/SubmitEx"); call.setEncodingStyle(null); call.setProperty(org.apache.axis.client.Call.SEND_TYPE_ATTR, Boolean.FALSE); call.setProperty(org.apache.axis.AxisEngine.PROP_DOMULTIREFS, Boolean.FALSE); call.setSOAPVersion(org.apache.axis.soap.SOAPConstants.SOAP11_CONSTANTS); call.setOperationName(new javax.xml.namespace.QName("", "SubmitEx")); String theService = "CreateDocument"; ArrayOfString parms = new ArrayOfString(); // not used ArrayOfKeyValue inKeyValues = new ArrayOfKeyValue(); inKeyValues.setKeyValue(new KeyValue[]{new KeyValue("Email", "rude@sofico.be")}) ; ArrayOfDoc inDocuments = new ArrayOfDoc(); inDocuments.setDoc(new Doc[]{new Doc("Data", new byte[0])}); String ret = (String) call.invoke( new Object[]{theService, parms, inKeyValues, inDocuments} ); // 1.log response msg ==> this message shows that there are 4 elements: // error // outKeyValues // outDocuments // progres logResponseMsg(call.getResponseMessage()); // 2.when i print ALL the outputparams I only see the first param. // when looking in the code that fills the map i see: // call.invoke ==> soapenvelope.getfirstbody ==> body.getfirstboy ==> getChildren().get(0)!!! (see SOAPBODY.getFirstBody) // ==> only the first param is put in the outputparam ... I expected it would contain the 4 elements that are present in the response MSG logOutputParams(call.getOutputParams()); // 3.when manually parsing it is possible to retrieve/decode/store the document from the response msg parseMsgManual(call.getResponseMessage()); } catch (MalformedURLException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (ServiceException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (RemoteException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } private static void parseMsgManual(Message msg) throws AxisFault{ System.out.println("\n\n manual parsing of the received params:"); Vector<Node> v = msg.getSOAPEnvelope().getBodyElements(); Iterator<Node> it2 = v.iterator(); while(it2.hasNext()){ Node cur= it2.next(); System.out.println(cur.getNodeName() ); if("outDocuments".equals(cur.getNodeName())){ Node n = cur.getFirstChild(); if(n != null){ String docName = null; byte[] content = null; NodeList docInfo = n.getChildNodes(); Node docID = docInfo.item(0); Node doc = docInfo.item(1); if(docID != null) docName = docID.getFirstChild().getNodeValue(); if(doc != null){ String tmp = doc.getFirstChild().getNodeValue(); content = Base64.decodeBuffer(tmp); } if(docName != null && content != null){ writeBytes(content, "c:/output.pdf"); } } } } } private static void logOutputParams(Map output){ System.out.println("Printing of all received output params"); Iterator it = output.keySet().iterator(); while(it.hasNext()){ Object key = it.next(); String val = (String)output.get(key); System.out.println(key + " : " + val); } } private static void logResponseMsg(Message msg) throws AxisFault, Exception{ String s = XMLUtils.DocumentToString(msg.getSOAPEnvelope().getAsDocument()); writeBytes(s.getBytes(), "c:/response.xml"); } // this msg is not relevant to the issue, just required do write the output in a file... private static final int BUFFER = 1024; private static boolean writeBytes(byte[] theBytes, String filePath) { boolean result = false; FileOutputStream lRepOut = null; try { lRepOut = new FileOutputStream(filePath, false); // Empty files are possible! if(theBytes==null) theBytes = new byte[0]; int length = theBytes.length; for (int i = 0; i < length; i += BUFFER) { int chunk = BUFFER; if(i+BUFFER > length){ // avoid index out of bounds when writing last part of file chunk = length - i; } lRepOut.write(theBytes, i, chunk); } result = true; } catch (java.io.IOException ex) { System.out.println("Failed to write to file '" + filePath + "' :" + ex.getMessage()); if (lRepOut != null) { try { lRepOut.close(); } catch (Exception ignoreClosingExc) { } } // throw the error so the user is informed. ex.printStackTrace(); } finally { try { if (lRepOut != null) { lRepOut.flush(); lRepOut.close(); } } catch (IOException e) { } } return result; } }
- 09-30-2010, 05:36 PM #2
Moderator
- Join Date
- Apr 2009
- Posts
- 10,480
- Rep Power
- 16
What sort of Java would that wsdl generate, using wsdl2java for example?
I can't think of a web service I've written that had multiple response nodes under the body, not that SOAP forbids that or anything...I'm just curious how it would be generated.
- 10-01-2010, 10:00 AM #3
Member
- Join Date
- Sep 2010
- Posts
- 3
- Rep Power
- 0
Hi thx for response :):
Good question (which will clarify my concern about the missing params :)):
The generate stub class contains the following operation:
The last 4 arguments will be updated by reference, with the result values of the outputparams:Java Code:public void submitEx(java.lang.String service, com.testcase.www.itpserver.wsdl.ArrayOfString parms, com.testcase.www.itpserver.wsdl.ArrayOfKeyValue inKeyValues, com.testcase.www.itpserver.wsdl.ArrayOfDoc inDocuments, javax.xml.rpc.holders.StringHolder submitExResult, com.testcase.www.itpserver.wsdl.holders.ArrayOfKeyValueHolder outKeyValues, com.testcase.www.itpserver.wsdl.holders.ArrayOfDocHolder outDocuments, com.testcase.www.itpserver.wsdl.holders.ArrayOfStringHolder progress)
The relevant code looks like this:
This is code generated using axis 1.4.Java Code:java.lang.Object _resp = _call.invoke(new java.lang.Object[] {service, parms, inKeyValues, inDocuments}); if (_resp instanceof java.rmi.RemoteException) { throw (java.rmi.RemoteException)_resp; } else { extractAttachments(_call); java.util.Map _output; _output = _call.getOutputParams(); try { submitExResult.value = (java.lang.String) _output.get(new javax.xml.namespace.QName("http://www.testcase.com/itpserver/wsdl", "error")); } catch (java.lang.Exception _exception) { submitExResult.value = (java.lang.String) org.apache.axis.utils.JavaUtils.convert(_output.get(new javax.xml.namespace.QName("http://www.testcase.com/itpserver/wsdl", "error")), java.lang.String.class); } try { outKeyValues.value = (com.testcase.www.itpserver.wsdl.ArrayOfKeyValue) _output.get(new javax.xml.namespace.QName("http://www.testcase.com/itpserver/wsdl", "outKeyValues")); } catch (java.lang.Exception _exception) { outKeyValues.value = (com.testcase.www.itpserver.wsdl.ArrayOfKeyValue) org.apache.axis.utils.JavaUtils.convert(_output.get(new javax.xml.namespace.QName("http://www.testcase.com/itpserver/wsdl", "outKeyValues")), com.testcase.www.itpserver.wsdl.ArrayOfKeyValue.class); } try { outDocuments.value = (com.testcase.www.itpserver.wsdl.ArrayOfDoc) _output.get(new javax.xml.namespace.QName("http://www.testcase.com/itpserver/wsdl", "outDocuments")); } catch (java.lang.Exception _exception) { outDocuments.value = (com.testcase.www.itpserver.wsdl.ArrayOfDoc) org.apache.axis.utils.JavaUtils.convert(_output.get(new javax.xml.namespace.QName("http://www.testcase.com/itpserver/wsdl", "outDocuments")), com.testcase.www.itpserver.wsdl.ArrayOfDoc.class); } try { progress.value = (com.testcase.www.itpserver.wsdl.ArrayOfString) _output.get(new javax.xml.namespace.QName("http://www.testcase.com/itpserver/wsdl", "progress")); } catch (java.lang.Exception _exception) { progress.value = (com.testcase.www.itpserver.wsdl.ArrayOfString) org.apache.axis.utils.JavaUtils.convert(_output.get(new javax.xml.namespace.QName("http://www.testcase.com/itpserver/wsdl", "progress")), com.testcase.www.itpserver.wsdl.ArrayOfString.class); }
It implies that I have all params should be returned by _call.getOutputParams();.
My code did not work, because i needed the 3th param (which contained a document) but I always only receive the first argument because that is the only one returned by _call.getOutputParams();
So my code did not work, even though it should have (at least that is what I think :) . Currently I read the soap response and parse it manually to retrieve all params, but I would like to get it working using the generated stubs.
- 10-01-2010, 10:24 AM #4
Moderator
- Join Date
- Apr 2009
- Posts
- 10,480
- Rep Power
- 16
Hmm.
It does sort of imply that's how it should work.
And thanks for showing the generated code...
So that generated code does exactly what you say in the first post, that is only the submitExResult attribute gets populated (from error), and the rest is null?
Did you step through the code to see that's what's happening by the way? I had a peek at the axis code but it's nto the neatest thing in the world...:)
- 10-01-2010, 10:52 AM #5
Member
- Join Date
- Sep 2010
- Posts
- 3
- Rep Power
- 0
Only the submitex contains a value because it is the only param in the returned map.
I have looked into the axis code which fills the map and they actually only take the first node under the soapbody element.
See the Call objects operation:
public Object invoke( RPCElement body ) throws AxisFault
You find:
SOAPBodyElement bodyEl = resEnv.getFirstBody();
Which uses eventually the SoapBody.getfirstbody:
The 0 indextaks the first child under the body.Java Code:SOAPBodyElement getFirstBody() throws AxisFault { if (!hasChildNodes()) return null; return (SOAPBodyElement)getChildren().get(0); }
The code in the Call class then loops the children of that node.
It seems the the getFirstBody method does not return the first body. But the first Node under the body. Could it be that they go 1 level to deep?
PS: I have tried finding axis mailing lists or forums but with no success the mialing lists all moved or don't exist anymore and no forum was foudn :(
Similar Threads
-
Server returned HTTP response code: 500.. i need help
By hardc0d3r in forum Java ServletReplies: 9Last Post: 03-12-2012, 08:08 PM -
Adding multiple sheets in Excel (apache POI)
By javanewbie in forum Advanced JavaReplies: 0Last Post: 06-22-2009, 04:51 AM -
Server returned HTTP response code: 500
By fuliangQ in forum JavaServer Pages (JSP) and JSTLReplies: 1Last Post: 04-09-2009, 03:55 AM -
java.io.Exception: Server returned HTTP response code: 403
By navishkumarb in forum Advanced JavaReplies: 1Last Post: 01-05-2008, 01:33 PM -
Server returned HTTP response code: 500
By Heather in forum Java ServletReplies: 1Last Post: 07-09-2007, 04:32 AM


LinkBack URL
About LinkBacks

Bookmarks