Servlet je speciální třída v jazyce Java, která běží v rámci servletové kontejneru. To je speciální web server, který je schopný hostovat právě servlety. Funkční verze servletu je dostupná na adrese http://rainbow.vse.cz:8000/rainbow/xulservlet.
Příklad B.2. Servlet generující XUL kód
package cz.vse.rainbow.servlets; // standard and servlet imports import java.io.*; import java.util.*; import javax.servlet.*; import javax.servlet.http.*; // WS imports import client.iface.*; import client.iface.struct.*; import org.idoox.wasp.Context; import org.idoox.wasp.MessageAttachment; import org.idoox.webservice.client.WebService; import org.idoox.webservice.client.WebServiceLookup; import org.idoox.webservice.client.WebServiceLookupException; // servlet which returns information about specific URL // as XUL document // URL should be passed by GET method in "url" parameter public class XULServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { // generate begin of XUL page response.setContentType( "application/vnd.mozilla.xul+xml; charset=utf-8"); PrintWriter out = response.getWriter(); out.println("<?xml version='1.0'?>\n" + "<?xml-stylesheet href='chrome://global/skin/' type='text/css'?>\n" + "<window xmlns='http://www.mozilla.org/keymaster/ gatekeeper/there.is.only.xul'>\n" + "<script type='application/x-javascript'>\n" + "function openTopWin( url )\n" + "{ window._content.location = url; }\n" + "</script>\n" + "<tree flex='1'>\n" + " <treecols>\n" + " <treecol flex='1'/>\n" + " <treecol flex='1'/>\n" + " </treecols>\n" + " <treechildren flex='1'>\n"); String googleHost = "http://api.google.com/search/beta2"; String metadataHost = "http://rainbow.vse.cz:8000/wasp/Metadata/"; String lingHost = "http://rainbow.vse.cz:7878"; try { //init the lookup WebServiceLookup lookup = (WebServiceLookup)Context.getInstance ("org.idoox.webservice.client.WebServiceLookup"); // ask Google for related pages GoogleSearchPort serviceGoogle = (GoogleSearchPort)lookup. lookup("http://api.google.com/GoogleSearch.wsdl", GoogleSearchPort.class,googleHost); GoogleSearchResult r = serviceGoogle.doGoogleSearch ("...heslo pro přístup ke službě...", "related:" + request.getParameter("url"), 0, 10, false, "", false, "", "", ""); out.println("<treeitem container='true' open='true'>\n" + "<treerow>\n" + "<treecell class='treecell-indent' label='Related pages' style='font-weight: bold'/>\n" + "</treerow>\n" + "<treechildren>\n"); for (int i=0; i < r.resultElements.length; i++) { String title = escapeXML(r.resultElements[i].title); String url = escapeXML(r.resultElements[i].URL); if (title.equals("")) title = url; out.println("<treeitem><treerow>\n" + "<treecell class='treecell-indent' style='color: blue' " + "label='" + title + "' " + "onclick=\"openTopWin('" + url + "')\"/>\n" + "</treerow></treeitem>\n"); } if (r.resultElements.length == 0) { out.println("<treeitem><treerow>\n" + "<treecell class='treecell-indent' style='color: blue' " + "label='No related pages'/>\n" + "</treerow></treeitem>\n"); } out.println("</treechildren></treeitem>\n"); // ask Metadata service for metadata Metadata serviceMetadata = (Metadata)lookup. lookup("http://rainbow.vse.cz:8000/wasp/Metadata/", Metadata.class,metadataHost); Metalist listtags = new Metalist(); MetalistHolder objmeta = new MetalistHolder(); objmeta.setValue(listtags); serviceMetadata.getTags(request.getParameter("url"), objmeta); listtags = objmeta.getValue(); out.println("<treeitem container='true' open='true'>\n" + "<treerow>\n" + "<treecell class='treecell-indent' label='Metadata' style='font-weight: bold'/>\n" + "</treerow>\n" + "<treechildren>\n"); for (int i=0; i< listtags.count; i++) { String metadata = escapeXML(listtags.metatags[i].name + ": " + listtags.metatags[i].content); out.println("<treeitem><treerow>\n" + "<treecell class='treecell-indent' " + "label='" + metadata + "'/>\n" + "</treerow></treeitem>\n"); } if (listtags.count == 0) { out.println("<treeitem><treerow>\n" + "<treecell class='treecell-indent' " + "label='No metadata found'/>\n" + "</treerow></treeitem>\n"); } out.println("</treechildren></treeitem>\n"); // ask Ling service for data LingService serviceLing = (LingService)lookup. lookup("http://rainbow.vse.cz/support/rb-ling.wsdl", LingService.class,lingHost); String sentences[] = serviceLing.extractSentences (request.getParameter("url")); out.println("<treeitem container='true' open='true'>\n" + "<treerow>\n" + "<treecell class='treecell-indent' label='Page indicators' style='font-weight: bold'/>\n" + "</treerow>\n" + "<treechildren>\n"); for (int i=0; i<sentences.length; i++) { out.println("<treeitem><treerow>\n" + "<treecell class='treecell-indent' label='" + escapeXML(sentences[i]) + "'/>\n" + "</treerow></treeitem>\n"); } if (sentences.length == 0) { out.println("<treeitem><treerow>\n" + "<treecell class='treecell-indent' " + "label='No indicators found'/>\n" + "</treerow></treeitem>\n"); } out.println("</treechildren></treeitem>\n"); } catch (WebServiceLookupException e) { out.println("Unable to call web-service."); } out.println("</treechildren></tree>\n</window>\n"); } // escapes XML significant characters by entities String escapeXML (String in) { String out = ""; for (int i=0; i< in.length(); i++) { if (in.charAt(i) == '<') out += "<"; else if (in.charAt(i) == '&') out += "&"; else if (in.charAt(i) == '\'') out += "'"; else if (in.charAt(i) == '\"') out += """; else out += in.charAt(i); } return out; } }