Cocoon and Web-Services
Transcription
Cocoon and Web-Services
Building a video search application with WS and Cocoon Michael Hielscher IIM O6 Content Introduction on WebServices What is a WebService How to use WebServices How can we use a WS inside of Cocoon Building a custom Cocoon-Generator Using a custom generator in your Sitemap Building an application for searching video files WS for searching videos Transforming WS-XML to HTML Introduction on WebServices WebServices can be compared with RPC like RMI or .NET Remoting Widely used also from companies like google, amazon… WebServices are XML based (the entire communication between Client and Service in general) WebServices are platform independent – can be implemented in many languages and systems. What is a WebService A WebService … … is an application running in a WebServer environment (like a typical web application) like on TomCat, or IIS … has an URL like a Webpage … offering one or more methods that the client can use … communicates over HTTP like a normal web application … requests and responses are written in SOAP (a XML format) … are self-describing What is a WebService WebService Consumer (Client) WebService Provider (Server) Application Logic Application Logic WS-Toolkit WS-Toolkit Message (SOAP) DB What is a WebService WebService Consumer (Client) Application Logic WS-Toolkit Describes WSDL Reads Message (SOAP) Transport HTTP Netzwerk TCP/IP WebService Provider (Server) Application Logic WS-Toolkit DB What is a WebService How can a Service describe him self? public String[] doGoogleSearch (String search) { … } How can a Scheme program deal with this ??? Netzwerkprogrammierung 7 What is a WebService WSDL Examples: http://www.webservicex.net/globalweather.asmx?wsdl http://api.google.com/GoogleSearch.wsdl WS build with Microsoft .NET offer a testing interface to explore the methods of a WebService: http://www.webservicex.net/globalweather.asmx http://www.webservicex.net/CreditCard.asmx What do you think about the last Service for your business application? How to use a WebService Many WS offer the so called REST interface and can accessed like a Servlet In larger applications the WSDL is used to generate so called “proxy” classes – objects that perform the RPC call in the background (like RMI Stubs). Short example of weather WS with Visual Studio 2005 How can we use a WS inside of Cocoon A WS provides output in XML Cocoon is processing XML in pipelines Idea: Call a WS and than use the output inside of a pipeline We need parameters for the method name and values like Country=Germany – where to specify inside of our Sitemap? How can we use a WS inside of Cocoon Typical Sitemap: <?xml version="1.0" encoding="UTF-8"?> <map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0"> <map:pipelines> <map:pipeline> <map:match pattern="index"> <map:generate type="file" src="helloworld.xml"/> <map:transform type="xslt" src="helloworld2html.xsl"/> <map:serialize type="html"/> </map:match> </map:pipeline> </map:pipelines> </map:sitemap> How can we use a WS inside of Cocoon New WS generator: <map:match pattern="weather"> <map:generate type="WebService" src="http://www.webservicex.net/globalweather.asmx"> <map:parameter name="Operation" value="GetWeather"/> <map:parameter name="CountryName" value="Germany"/> <map:parameter name="CityName" value="Berlin"/> </map:generate> <map:transform src="weather2html.xsl"/> <map:serialize type="xhtml"/> </map:match> Building a custom Cocoon-Generator Cocoon offers multiple generator base classes we can derive from. The one with the most build in features is the ServiceableGenerator we use this one. Starting with a static content XML generator (generates always the same static XML output) Building a custom Cocoon-Generator import …; // various imports here public class WSGenerator extends ServiceableGenerator { public void generate() throws IOException, SAXException, ProcessingException { String message = “<PAGE><TITLE>Testing</TITLE></PAGE>”; InputSource inputSource = new InputSource(new StringReader(message)); SAXParser parser = null; try { parser = (SAXParser) this.manager.lookup(SAXParser.ROLE); parser.parse(inputSource, super.xmlConsumer); } catch (SAXException e) { throw e; } catch (Exception e) { throw new ProcessingException("Exception: ", e); } finally { if (parser != null) this.manager.release(parser); } }} Building a custom Cocoon-Generator In our Sitemap we used parameters for the generator we need to access them inside of the generator import …; // various imports here public class WSGenerator extends ServiceableGenerator { public void generate() throws …{ String message = “<PAGE><TITLE>Testing</TITLE><PARAMS>”; String[] params = parameters.getNames(); for (int i = 0; i < params.length; i++) message += “<PARAM>” + params[i] + “</PARAM>”; message += “</PARAMS></PAGE>”; ... // like in last example Building a custom Cocoon-Generator The Sitemap entry again: <map:match pattern="weather"> <map:generate type="WebService" src="http://www.webservicex.net/globalweather.asmx"> <map:parameter name="Operation" value="GetWeather"/> <map:parameter name="CountryName" value="Germany"/> <map:parameter name="CityName" value="Berlin"/> </map:generate> <map:transform src="weather2html.xsl"/> <map:serialize type="xhtml"/> </map:match> Building a custom Cocoon-Generator import …; // various imports here public class WSGenerator extends ServiceableGenerator { public void generate() throws … { String url = this.source + "/" + parameters.getParameter("Operation"); String[] params = parameters.getNames(); boolean first = true; for (int i = 0; i < params.length; i++) { if (params[i].equals("Operation")) continue; if (first) { url += "?“; first = false; } else { url += "&“; } try { url += params[i]+"="+parameters.getParameter(params[i]); } catch (ParameterException e) {} } Building a custom Cocoon-Generator String message = ""; URL Service = new URL(url); try { InputStream urlStream = Service.openStream(); // read in entire file byte b[] = new byte[1000]; int numRead = urlStream.read(b); message = new String(b, 0, numRead); while (numRead != -1) { numRead = urlStream.read(b); if (numRead != -1) { String newCommands = new String(b,0,numRead); message += newCommands; } } urlStream.close(); } catch (IOException e) { throw new ProcessingException("Web service error", e); } ... // like in last example Using a custom generator in your Sitemap How can we use our generator now? We need to declare the generator in the component section of the sitemap Than we can use it like any other generator in Cocoon Using a custom generator in your Sitemap <?xml version="1.0" encoding="UTF-8"?> <map:sitemap xmlns:map="http://apache.org/cocoon/sitemap/1.0"> <map:components> <map:matchers default="wildcard"> <map:matcher name="wildcard“ src="org.apache.cocoon.matching.WildcardURIMatcher"/> </map:matchers> <map:generators> <map:generator name="WebService" src="WebServiceGenerator.WSGenerator"/> </map:generators> </map:components> <map:pipelines> Building an application for searching video files We could define a lot of projects using our new WebService generator I have choose a WS with a lot of features so we can see the power of cocoon and WS Goal: We all know the google image search It would be great to have a similar search engine for video files on platforms like YouTube, MyVideo … We want a tiny and fast search (no advertisement) Building an application for searching video files The search is performed by a WS offered by blinkx.com We need to call the WS and transform the XML output into a beautiful HTML page We don’t want to program any cocoon-action or something in Java – only use the Sitemap and XSL Building an application for searching video files Defining the Sitemap and use request parameters: <map:pipelines> <map:pipeline> <map:match pattern="video"> <map:act type="request"> <map:parameter name="parameters" value="true"/> <map:generate type="WebService“ src="http://usp1.blinkx.com/partnerapi/user/"> <map:parameter name="Operation" value="api.php"/> <map:parameter name="uid" value="d3ac0e"/> <map:parameter name="Text" value="{searchtext}"/> <map:parameter name="Start" value="{pos}"/> <map:parameter name="MaxResults" value="{results}"/> <map:parameter name="AdultFilter" value="{adultfilter}"/> </map:generate> <map:transform src="video2html.xsl"/> <map:serialize type="xhtml"/> </map:act> </map:match> </map:pipeline> </map:pipelines> WS for searching video files For XSL we need to look on the output of the WS first: <?xml version="1.0" encoding="UTF-8" ?> <autnresponse xmlns:autn="http://schemas.autonomy.com/aci/"> <action>QUERY</action> <response>SUCCESS</response> <responsedata> <autn:numhits>10</autn:numhits> <autn:totalhits>317648</autn:totalhits> <autn:hit> <autn:reference>http://www.blinkx.com/…</autn:reference> <autn:title>Firefighter Catches 3 People Who Jumped Out Window</autn:title> <autn:summary> Stockton Firefighter Mick Connolly is no stranger to fierce flames. Last night, lives were immediate danger. </autn:summary> WS for searching video files <autn:content> <DOCUMENT> <CHANNEL>CBSSacramento</CHANNEL> <TYPE>Video</TYPE> <DOMAIN>http://www.cbs13.com/video</DOMAIN> <FOOTERIMAGE>http://cdn99.blinkx.com/store/images/footers/cbssacramento.gif</FOOTERIMAGE> <ALTIMAGE>http://cdn99.blinkx.com/store/images/defaultswf/cbs.jpg</ALTIMAGE> <STATICPREVIEW>http://…</STATICPREVIEW> <IMAGE>http://…/22760563_swf_0.swf</IMAGE> <MEDIA_TYPE>video/x-ms-wmv</MEDIA_TYPE> <MEDIA_TYPE_STRING>Windows Media</MEDIA_TYPE_STRING> </DOCUMENT> </autn:content> <autn:date>1181356390</autn:date> <autn:datestring>7 hours ago</autn:datestring> … many of such hits WS for searching video files We get a lot of information from the WS We don’t need all of them. Selecting only a few that for our search engine like: preview image, title of the clip, URL where to watch the movie, number of hits, … Logic (Turn pages, number of results displayed per page,…) is done in JavaScript embedded into the HTML Transforming WS-XML to HTML XSLT is used to transform XML to HTML One fixed size box for each video we found containing the preview image, title and a link for watching the movie. About one A4 page for the XSL file (not too big at all) Result – Video Search Application Try your self: http://84.16.228.218:8080/cocoon/WebService/video Conclusion WebServices can be used with XML pipelines like Cocoon really well Without “programming” we can create a useful application Creating own generators can be useful in Cocoon but is not very well documented