Me again :)

I had a lot of thinking today and a lot of help from the irc (irc.freenode.net#cocoon). Thanks joose and ugocei!

since it is kind of working now, i have set up a wikipage and hope. its not that crappy:

        http://wiki.apache.org/cocoon/WebServiceServer

hth, jan

Jan Hinzmann wrote:
Hi *,

I'm working on a little Webservice and I'm needing help on generating and
serializing xml-content from the flowscript to the sitemap and viceversa.

My approach is to generate a received SOAP-Envelope with a StreamGenerator and extracting the called method and the arguments using xslt and flow. Then I will be using the flowscript to compute the request and finally serialize an answer-envelope to the client.

For the ones of you who are in a hurry: go to the bottom of this mail to find my questions.


Let me introduce a (little) example (I'm sorry, it has become a bit bigger than I expected. But I hope it is worth reading it):


Imagine, there is a little Webservice, which has a echo-method:

public class Webservice(){
    public synchronised String echo(String echo){
        return echo;
    }
}

Now customers are sending SOAP-envelopes (using a middleware like axis) like the following:

<?xml version="1.0" encoding="ISO-8859-1"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/";
xmlns:xsd="http://www.w3.org/2001/XMLSchema";
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance";>
<soapenv:Body>
<ns1:echo soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/";
xmlns:ns1="CodataWS">
<ns1:arg0 xsi:type="xsd:string">Hello Echo!?</ns1:arg0>
</ns1:echo>
</soapenv:Body>
</soapenv:Envelope>


this I'm generating with a org.apache.cocoon.generation.StreamGenerator and
forward it from the sitemap to the flowscript with:

<!-- == Webservice by Cocoon == -->
<map:pipeline>
<map:match pattern="webservice">
<map:call function="mainWS"/>
</map:match>
<!-- getting the soap-envelope -->
<map:match pattern="soapData">
<map:generate type="stream"/>
<map:serialize type="xml"/>
</map:match>
...


The first matcher calls a flowscript, which will request the envelope and save it in an ByteArrayOutputStream using the second matcher:

function mainWS(){
var soapData = new java.io.ByteArrayOutputStream();
clog("SOAP-envelope received, processing the request:\n");
//getting the envelope out of the request (can be done only once)
cocoon.processPipelineTo("soapData", null, soapData);
clog("Request was:\n" + soapData + "\n");
...


now that I have saved the soapData in an ByteArrayOutputStream, I'm sending it
back to the Sitemap, to get the Method out of the envelope ('echo' in this case) using xslt:


var soapMethod = new java.io.ByteArrayOutputStream();
cocoon.processPipelineTo("soapMethod", {"soapData":soapData}, soapMethod); clog("soapMethod: " + soapMethod + "\n");


OR
var soapMethod = new java.io.ByteArrayOutputStream();
var pipeutil = cocoon.createObject(Packages.org.apache.cocoon.components.flow.util.PipelineUtil);


pipeutil.processToStream("soapMethod", {"soapData":soapData}, soapMethod); both methods seem to affect the same(?)

Back in the sitemap I've tried to generate this parameter with

  <!-- which Method is called? -->
  <map:match pattern="soapMethod">
    <map:generate type="stream" src="{flow-attribute:soapData}"/>
  ...

but that doesn't seem to work. Here (and generally :)) I would appreciate any suggestions!

For now I'm passing the content as parameter to the transformation:

  <!-- which Method is called? -->
  <map:match pattern="soapMethod">
    <map:generate src="xml/dummy.xml"/>
    <map:transform src="xsl/soapMethod.xsl">
      <map:parameter name="soapData" value="{flow-attribute:soapData}"/>
    </map:transform>
    <map:transform src="xsl/soapMethodNow.xsl"/>
    <map:serialize type="xml"/>
  </map:match>

the two stylesheets should extract the name of the method to be called (this will be found as local-name() in the first node after /Envelope/Body) and therefore looks like:

the first stylesheet should simply inject the soap-envelope-content soapMethod.xsl:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
<xsl:output method="xml"/>
<xsl:param name="soapData"/>
<xsl:template match="/">
<xsl:value-of select="$soapData"/>
</xsl:template>


</xsl:stylesheet>

and the second one should lookup the methodname
soapMethodNow.xsl:

<?xml version="1.0"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform";>
<xsl:output method="text"/>
<xsl:template match="/Envelope/Body">
<xsl:apply-templates/>
</xsl:template>
<xsl:template match="*[1]">
<xsl value-of select="local-name()"/>
</xsl:template>


</xsl:stylesheet>

strangely the first stylesheet produces output like:

<?xml version="1.0" encoding="ISO-8859-1"?>
&lt;?xml version="1.0" encoding="ISO-8859-1"?&gt;
&lt;soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"; xmlns:xsd="http://www.w3.org/2001/XMLSchema"; xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"&gt;
&lt;soapenv:Body&gt;
&lt;ns1:echo soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"; xmlns:ns1="CodataWS"&gt;
&lt;ns1:arg0 xsi:type="xsd:string"&gt;Hello Echo!?&lt;/ns1:arg0&gt;
&lt;/ns1:echo&gt;
&lt;/soapenv:Body&gt;
&lt;/soapenv:Envelope&gt;


So why are the '<' and '>' are replaced with there corresponding htmlthingies?


What do you think about this approach? Any suggestions are welcome.


-- Gruss, Jan Hinzmann

---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]



Reply via email to