aboutsummaryrefslogtreecommitdiffstats
path: root/src/documentation/content/xdocs/trunk/servlets.xml
diff options
context:
space:
mode:
Diffstat (limited to 'src/documentation/content/xdocs/trunk/servlets.xml')
-rw-r--r--src/documentation/content/xdocs/trunk/servlets.xml255
1 files changed, 255 insertions, 0 deletions
diff --git a/src/documentation/content/xdocs/trunk/servlets.xml b/src/documentation/content/xdocs/trunk/servlets.xml
new file mode 100644
index 000000000..7a3f6493f
--- /dev/null
+++ b/src/documentation/content/xdocs/trunk/servlets.xml
@@ -0,0 +1,255 @@
+<?xml version="1.0" standalone="no"?>
+<!--
+ Copyright 1999-2005 The Apache Software Foundation
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+-->
+<!-- $Id$ -->
+<!DOCTYPE document PUBLIC "-//APACHE//DTD Documentation V2.0//EN" "http://forrest.apache.org/dtd/document-v20.dtd">
+<document>
+ <header>
+ <title>Servlets</title>
+ <subtitle>How to use Apache FOP in a Servlet</subtitle>
+ <version>$Revision$</version>
+ </header>
+ <body>
+ <section id="overview">
+ <title>Overview</title>
+ <p>
+ This page discusses topic all around using Apache FOP in a servlet environment.
+ </p>
+ </section>
+ <section id="example-servlets">
+ <title>Example Servlets in the FOP distribution</title>
+ <p>
+ In the directory {fop-dir}/src/java/org/apache/fop/servlet, you'll find a working example
+ of a FOP-enabled servlet.
+ </p>
+ <p>
+ The servlet is automatically built when you build Apache FOP using the supplied Ant script. After building
+ the servlet, drop fop.war into the webapps directory of Apache Tomcat (or any other web container). Then, you can use
+ URLs like the following to generate PDF files:
+ </p>
+ <ul>
+ <li>http://localhost:8080/fop/fop?fo=/home/path/to/fofile.fo</li>
+ <li>http://localhost:8080/fop/fop?xml=/home/path/to/xmlfile.xml&amp;xsl=/home/path/to/xslfile.xsl</li>
+ </ul>
+ <p/>
+ <p>The source code for the servlet can be found under {fop-dir}/src/java/org/apache/fop/servlet/FopServlet.java.</p>
+ </section>
+ <section id="servlet">
+ <title>Create your own Servlet</title>
+ <note>
+ This section assumes you are familiar with <a href="embedding.html">embedding FOP</a>.
+ </note>
+ <section id="minimal-servlet">
+ <title>A minimal Servlet</title>
+ <p>
+ Here is a minimal code snippet to demonstrate the basics:
+ </p>
+ <source>public void doGet(HttpServletRequest request,
+ HttpServletResponse response) throws ServletException {
+ try {
+ response.setContentType("application/pdf");
+ Fop fop = new Fop(Constants.RENDER_PDF);
+ fop.setOutputStream(response.getOutputStream());
+ TransformerFactory factory = TransformerFactory.newInstance();
+ Transformer transformer = factory.newTransformer();
+ Source src = new StreamSource("foo.fo");
+ Result res = new SAXResult(fop.getDefaultHandler());
+ transformer.transform(src, res);
+ } catch (Exception ex) {
+ throw new ServletException(ex);
+ }
+}</source>
+ <note>
+ There are numerous problems with the code snippet above.
+ Its purpose is only to demonstrate the basic concepts.
+ See below for details.
+ </note>
+ </section>
+ <section id="xslt">
+ <title>Adding XSL tranformation (XSLT)</title>
+ <p>
+ A common requirement is the to transform an XML source to
+ XSL-FO using an XSL transformation. It is recommended to use
+ JAXP for this task. The following snippet shows the basic
+ code:
+ </p>
+ <source>
+protected TransformerFactory transformerFactory;
+
+public void init() throws ServletException {
+ this.transformerFactory = TransformerFactory.newInstance();
+}
+
+[..]
+
+ //Setup FOP
+ Fop fop = new Fop(Constants.RENDER_PDF);
+
+ //Setup a buffer to obtain the content length
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ fop.setOutputStream(out);
+
+ //Setup Transformer
+ Source xsltSrc = new StreamSource(new File("foo-xml2fo.xsl"));
+ Transformer transformer = this.transformerFactory.newTransformer(xsltSrc);
+
+ //Make sure the XSL transformation's result is piped through to FOP
+ Result res = new SAXResult(driver.getDefaultHandler());
+
+ //Setup input
+ Source src = new StreamSource(new File("foo.xml"));
+
+ //Start the transformation and rendering process
+ transformer.transform(src, res);
+
+ //Prepare response
+ response.setContentType("application/pdf");
+ response.setContentLength(out.size());
+
+ //Send content to Browser
+ response.getOutputStream().write(out.toByteArray());
+ response.getOutputStream().flush();</source>
+ <note>
+ Buffering the generated PDF in a ByteArrayOutputStream is done to avoid potential
+ problems with the Acrobat Reader Plug-in in Microsoft Internet Explorer.
+ </note>
+ <p>
+ The <code>Source</code> instance used above is simply an
+ example. If you have to read the XML from a string, supply
+ a <code>new StreamSource(new
+ StringReader(xmlstring))</code>. Constructing and reparsing
+ an XML string is generally less desirable than using a
+ SAXSource if you generate your XML. You can alternatively
+ supply a DOMSource as well. You may also use dynamically
+ generated XSL if you like.
+ </p>
+ <p>
+ Because you have an explicit <code>Transformer</code> object, you can also use it to
+ explicitly set parameters for the transformation run.
+ </p>
+ </section>
+ <section id="cfg">
+ <title>Custom configuration</title>
+ <p>
+ You can easily set up your own FOUserAgent as demonstrated on the <a href="embedding.html">Embedding page</a>.
+ </p>
+ </section>
+ <section id="performance">
+ <title>Improving performance</title>
+ <p>
+ There are several options to consider:
+ </p>
+ <ul>
+ <li>
+ Instead of java.io.ByteArrayOutputStream consider using the ByteArrayOutputStream
+ implementation from the <a href="ext:jakarta/commons/io">Jakarta Commons IO project</a> which allocates less memory.
+ The full class name is: <code>org.apache.commons.io.output.ByteArrayOutputStream</code>
+ </li>
+ <li>
+ In certain cases it can help to write the generated PDF to a temporary file so
+ you can quickly reuse the file. This is especially useful, if Internet Explorer
+ calls the servlet multiple times with the same request or if you often generate
+ equal PDFs.
+ </li>
+ </ul>
+ <p>
+ Of course, the
+ <a href="embedding.html#performance">performance hints from the Embedding page</a>
+ apply here, too.
+ </p>
+ </section>
+ </section>
+ <section id="ie">
+ <title>Notes on Microsoft Internet Explorer</title>
+ <p>
+ Some versions of Internet Explorer will not automatically show the PDF or call the servlet multiple times.
+ These are well-known limitations of Internet Explorer and are not a problem of the servlet.
+ However, Internet Explorer can still be used to download the PDF so that it can be viewed later.
+ Here are some suggestions in this context:
+ </p>
+ <ul>
+ <li>
+ Use an URL ending in <code>.pdf</code>, like
+ <code>http://myserver/servlet/stuff.pdf</code>. Yes, the servlet can
+ be configured to handle this. If the URL has to contain parameters,
+ try to have <strong>both</strong> the base URL as well as the last parameter end in
+ <code>.pdf</code>, if necessary append a dummy parameter, like
+ <code>http://myserver/servlet/stuff.pdf?par1=a&amp;par2=b&amp;d=.pdf</code>. The
+ effect may depend on IEx version.
+ </li>
+ <li>
+ Give IEx the opportunity to cache. In particular, ensure the
+ server does not set any headers causing IEx not to cache the
+ content. This may be a real problem if the document is sent
+ over HTTPS, because most IEx installations will by default
+ <em>not</em> cache any content retrieved over HTTPS.
+ Setting the <code>Expires</code> header entry may help in
+ this case:<br/> <code>response.setDateHeader("Expires",
+ System.currentTimeMillis() + cacheExpiringDuration *
+ 1000);</code><br/> Consult your server manual and the
+ relevant RFCs for further details on HTTP headers and
+ caching.
+ </li>
+ <li>
+ Cache in the server. It may help to include a parameter in
+ the URL which has a timestamp as the value min order to
+ decide whether a request is repeated. IEx is reported to
+ retrieve a document up to three times, but never more often.
+ </li>
+ </ul>
+ </section>
+ <section id="servlet-engine">
+ <title>Servlet Engines</title>
+ <p>
+ When using a servlet engine, there are potential CLASSPATH issues, and potential conflicts
+ with existing XML/XSLT libraries. Servlet containers also often use their own classloaders
+ for loading webapps, which can cause bugs and security problems.
+ </p>
+ <section id="tomcat">
+ <title>Tomcat</title>
+ <p>
+ Check Tomcat's documentation for detailed instructions about installing FOP and Cocoon.
+ There are known bugs that must be addressed, particularly for Tomcat 4.0.3.
+ </p>
+ </section>
+ <section id="websphere">
+ <title>WebSphere 3.5</title>
+ <p>
+ Put a copy of a working parser in some directory where WebSphere can access it.
+ For example, if /usr/webapps/yourapp/servlets is the CLASSPATH for your servlets,
+ copy the Xerces jar into it (any other directory would also be fine).
+ Do not add the jar to the servlet CLASSPATH, but add it to the CLASSPATH of the
+ application server which contains your web application.
+ In the WebSphere administration console, click on the "environment" button in the
+ "general" tab. In the "variable name" box, enter "CLASSPATH".
+ In the "value" box, enter the correct path to the parser jar file
+ (/usr/webapps/yourapp/servlets/Xerces.jar in our example here).
+ Press "OK", then apply the change and restart the application server.
+ </p>
+ </section>
+ </section>
+ <section id="complex-usecases">
+ <title>Handling complex use cases</title>
+ <p>
+ Sometimes the requirements for a servlet get quite sophisticated: SQL data sources,
+ multiple XSL transformations, merging of several datasources etc. In such a case
+ consider using <a class="fork" href="ext:cocoon">Apache Cocoon</a> instead
+ of a custom servlet to accomplish your goal.
+ </p>
+ </section>
+ </body>
+</document>
+<!-- Last Line of $RCSfile$ -->