aboutsummaryrefslogtreecommitdiffstats
path: root/src/documentation/content/xdocs/1.1/servlets.xml
diff options
context:
space:
mode:
Diffstat (limited to 'src/documentation/content/xdocs/1.1/servlets.xml')
-rw-r--r--src/documentation/content/xdocs/1.1/servlets.xml325
1 files changed, 325 insertions, 0 deletions
diff --git a/src/documentation/content/xdocs/1.1/servlets.xml b/src/documentation/content/xdocs/1.1/servlets.xml
new file mode 100644
index 000000000..dd2df4351
--- /dev/null
+++ b/src/documentation/content/xdocs/1.1/servlets.xml
@@ -0,0 +1,325 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!--
+ Licensed to the Apache Software Foundation (ASF) under one or more
+ contributor license agreements. See the NOTICE file distributed with
+ this work for additional information regarding copyright ownership.
+ The ASF licenses this file to You 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>Apache™ FOP: 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>
+ <note>
+ This example servlet should not be used on a public web server connected to the Internet as it does not contain
+ any measures to prevent Denial-of-Service-Attacks. It is provided as an example and as a starting point for
+ your own servlet.
+ </note>
+ </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>private FopFactory fopFactory = FopFactory.newInstance();
+private TransformerFactory tFactory = TransformerFactory.newInstance();
+
+public void doGet(HttpServletRequest request,
+ HttpServletResponse response) throws ServletException {
+ try {
+ response.setContentType("application/pdf");
+ Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, response.getOutputStream());
+ Transformer transformer = tFactory.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 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>private FopFactory fopFactory = FopFactory.newInstance();
+private TransformerFactory tFactory = TransformerFactory.newInstance();
+
+public void init() throws ServletException {
+ //Optionally customize the FopFactory and TransformerFactory here
+}
+
+[..]
+
+ //Setup a buffer to obtain the content length
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+
+ //Setup FOP
+ Fop fop = fopFactory.newFop(MimeConstants.MIME_PDF, out);
+
+ //Setup Transformer
+ Source xsltSrc = new StreamSource(new File("foo-xml2fo.xsl"));
+ Transformer transformer = tFactory.newTransformer(xsltSrc);
+
+ //Make sure the XSL transformation's result is piped through to FOP
+ Result res = new SAXResult(fop.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
+ explicitely 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: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 id="uriresolver">
+ <title>Accessing resources in your web application</title>
+ <p>
+ Often, you will want to use resources (stylesheets, images etc.) which are bundled with
+ your web application. FOP provides a URIResolver implementation that lets you access
+ files via the Servlet's ServletContext. The class is called
+ <code>org.apache.fop.servlet.ServletContextURIResolver</code>.
+ </p>
+ <p>
+ Here's how to set it up in your servlet. Instantiate a new instance in the servlet's
+ init() method:
+ </p>
+ <source><![CDATA[
+ /** URIResolver for use by this servlet */
+ protected URIResolver uriResolver;
+
+ public void init() throws ServletException {
+ this.uriResolver = new ServletContextURIResolver(getServletContext());
+ [..]
+ }]]></source>
+ <p>
+ The ServletContextURIResolver reacts on URIs beginning with "servlet-context:". If you
+ want to access an image in a subdirectory of your web application, you could, for
+ example, use: "servlet-context:/images/myimage.png". Don't forget the leading slash
+ after the colon!
+ </p>
+ <p>
+ Further down, you can use the URIResolver for various things:
+ </p>
+ <ul>
+ <li>
+ With the Transformer (JAXP/XSLT) so things like document() functions can resolver
+ "servlet-context:" URIs.
+ </li>
+ <li>
+ With the FopFactory so every resource FOP loads can be loaded using a "servlet-context:"
+ URI.
+ </li>
+ <li>
+ You can the ServletContextURIResolver yourself in your servlet code to access
+ stylesheets or XML files bundled with your web application.
+ </li>
+ </ul>
+ <p>
+ Here are some example snippets:
+ </p>
+ <source><![CDATA[
+//Setting up the JAXP TransformerFactory
+this.transFactory = TransformerFactory.newInstance();
+this.transFactory.setURIResolver(this.uriResolver);
+
+[..]
+
+//Setting up the FOP factory
+this.fopFactory = FopFactory.newInstance();
+this.fopFactory.setURIResolver(this.uriResolver);
+
+[..]
+
+//The stylesheet for the JAXP Transfomer
+Source xsltSrc = this.uriResolver.resolve(
+ "servlet-context:/xslt/mystylesheet.xsl", null);
+Transformer transformer = this.transFactory.newTransformer(xsltSrc);
+transformer.setURIResolver(this.uriResolver);]]></source>
+ </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> \ No newline at end of file