# FOP - XSLT Transformierung mit Parametern



## ermod (26. Jul 2010)

Hallo,

ich habe mir einen Tomcat 5.5 mit Apache FOP 1.0 aufgesetzt, die fop.war befindet sich ordnungsgemäß im webapps-Ordner und meine XML/XSL bzw. FO Testdokumente im Ordner temp.

Wenn ich nun http://localhost:8180/fop/fop?fo=/Pfad/zu/meiner/FO-Datei ausführe, generiert mir FOP eine PDF.

Leider funktioniert das Ganze mit http://localhost/fop/fop?xml=/pfad/zur/XML-Datei&xsl=/pfad/zur/XSL-Datei nicht - es kommt immer die Fehlermeldung:

No 'fo' request param given.

Ich habe auch schon die ein oder andere Lösung aus dem Netz ausprobiert. Im Moment nutze ich das standard FopServlet.java, in dem meines Erachtens (bin Newbie) die XML/XSL Parameterisierung vorgesehen ist. Die Fehlermeldung lässt mich aber vermuten, dass nur die Angabe von FO-Parametern vorgesehen ist.

Danke für Eure Hilfe
Gruss Dom


----------



## SlaterB (26. Jul 2010)

richtig, der Code um eine FO-Datei umzuwandeln ist ein anderer als eine XSL-Datei zu transformieren,
welchen Java-Code du verwendest schreibst du nicht,

allgemein sollte sich alles in Anleitungen finden lassen, siehe z.B.
Servlets

unter 
> A minimal Servlet
stehen 15 Code-Zeilen wo nur von einer FO-Datei die Rede ist,

danach kommt
> Adding XSL tranformation (XSLT)
dann sind es 30 Zeilen und es tauchen auch XSL + XML auf,

einfacher gehts eigentlich nicht zu verstehen 
gut möglich aber dass du eine andere Version hast/ mein zufälliger google-Link veraltet ist,
der Code ändert sich von Version zu Version


----------



## ermod (26. Jul 2010)

Erstmal danke für die morgentliche Hilfe. Die Seite kenne ich natürlich schon und habe zwischenzeitlich Versuche mit den Snippets gestartet - leider ohne Erfolg.

Also ich gehe in das Root-Verzeichnis der FOP-Source und führe dort den ANT-Befehl aus, woraufhin die fop.war im Verzeichnis "Build" entsteht. Da sich dass standard FopServlet.java in /fop/src/java/org/apache/fop/servlet befindet, wird das doch zur Grundlage des Builds, oder bin ich da voll auf dem falschen Dampfer. Im folgenden poste ich mal einen Auszug aus dem FopServlet.java - bei der doGet-Methode sind drei Parameter berücksichtigt: FO, XML & XSLT. Warum nimmt das Servlet dann nur FO-Parameter an?

Ich verstehe den Text unter der Headline "Example Servlets in the FOP distribution" auch so, dass eben ein Ansprechen des FOP standardmäßig unter FO bzw. XML/XSL möglich ist.

Mein Lösungsansatz war jetzt, dass ich aus dem Ordner Examples das "ExampleXML2PDF.java" in den o.a. /servlet Ordner kopiert habe und dann ein ANT-Build ausgeführt habe - ohne Erfolg. Denselben Vorgang habe auch noch mit den Snippets von Deinem Link gemacht - wiederum ohne Erfolg.


```
/**
     * {@inheritDoc}
     */
    public void doGet(HttpServletRequest request,
                      HttpServletResponse response) throws ServletException {
        try {
            //Get parameters
            String foParam = request.getParameter(FO_REQUEST_PARAM);
            String xmlParam = request.getParameter(XML_REQUEST_PARAM);
            String xsltParam = request.getParameter(XSLT_REQUEST_PARAM);

            //Analyze parameters and decide with method to use
            if (foParam != null) {
                renderFO(foParam, response);
            } else if ((xmlParam != null) && (xsltParam != null)) {
                renderXML(xmlParam, xsltParam, response);
            } else {
                response.setContentType("text/html");
                PrintWriter out = response.getWriter();
                out.println("<html><head><title>Error</title></head>\n"
                          + "<body><h1>FopServlet Error</h1><h3>No 'fo' "
                          + "request param given.</body></html>");
            }
        } catch (Exception ex) {
            throw new ServletException(ex);
        }
    }
```

Danke nochmals
Gruss


----------



## SlaterB (26. Jul 2010)

zum Deployment kann ich wenig sagen, programmiere aktuell keine Web-Projekte,
allgemein kann man Java-Klassen immer da programmieren wo man will und alles andere so konfigurieren dass es klappt,
man muss nicht in irgendeinem Verzeichnis sein usw.,

halte dich dazu lieber an ganz normale Web-Tutorials, 
erstelle dir Servlets so wie allgemein bekannt und kopiere dann lediglich den Fop-Code da rein,
mehr als eine von diversen Libraries in Build-Path ist dann erstmal nicht nötig,

Pfade zu Dateien auf der Festplatte müssen natürlich passend formuliert sein

andererseits läuft bei dir das Servlet ja, insofern dazu vielleicht gar keine Frage offen 

--------

das Servlet macht verschiedene Dinge, wenn es kompiliert dann wird es so wahrscheinlich richtig sein,
was genau passiert hängt von den Parametern ab, keine Ahnung was du da wie wo wann warum sendest,
vielleicht schickst du immer die Pfade zu allen drei Dateien oder durch ein ungünstiges Formular ist der foParam nicht null sondern z.B. "" selbst wenn nichts angegeben ist,
ändere das if oder verwende direkt verschiedene Servlets/ verschiedene Formulare

das ist aber eher eine allgemeine Web-Frage, hat mit der Fop-Verarbeitung wenig zu tun falls du nicht auch noch einen vorgegebenen Client/ HTML-Formular verwendest

allgemein wäre dann die Übung erstmal einfache Parameter 'Test' einzulesen und korrekt testweise zu verarbeiten


----------



## nocturne (26. Jul 2010)

Wenn du nur PDF benutzt kannst du auch direkt HTML verwenden.
Hier eine gute Möglichkeit pdf's zu erstellen:

```
package org....;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.io.StringReader;
import java.net.URL;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.parsers.DocumentBuilder;

import org.apache.pdfbox.PDFBox;
import org.apache.pdfbox.pdfparser.PDFParser;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDDocumentInformation;
import org.htmlcleaner.HtmlCleaner;
import org.htmlcleaner.PrettyXmlSerializer;
import org.htmlcleaner.TagNode;
import org.w3c.dom.Document;
import org.xhtmlrenderer.pdf.ITextRenderer;
import org.xml.sax.InputSource;

import com.sun.org.apache.xerces.internal.jaxp.DocumentBuilderFactoryImpl;

public class PDFServlet extends HttpServlet {

	DocumentBuilderFactoryImpl dbfi = new DocumentBuilderFactoryImpl();

	@Override
	protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
		// TODO Auto-generated method stub
		try {
			resp.setContentType("application/pdf");

			HttpServletResponse response = (HttpServletResponse) resp;
			HtmlCleaner cleaner = new HtmlCleaner();

			ByteArrayOutputStream baos = new ByteArrayOutputStream();
			OutputStreamWriter osw = new OutputStreamWriter(baos);

			URL url = new URL(req.getRequestURL() + ".jsp?" + req.getQueryString());
			InputStream t = (InputStream) url.openStream();
			TagNode node = cleaner.clean(t);
			t.close();
			node.serialize(new PrettyXmlSerializer(cleaner.getProperties()), osw);
			osw.close();

			String xhtml = baos.toString();

			StringReader contentReader = new StringReader(xhtml);
			InputSource source = new InputSource(contentReader);

			DocumentBuilder dbi = dbfi.newDocumentBuilder();
			Document xhtmlContent = dbi.parse(source);

			ITextRenderer renderer = new ITextRenderer();

			renderer.getFontResolver().addFont(getClass().getResource("/wingding.ttf") + "", false);
			renderer.setDocument(xhtmlContent, "");
			renderer.layout();

			PDFBox box = new PDFBox();

			ByteArrayOutputStream pdfdata = new ByteArrayOutputStream();
			renderer.createPDF(pdfdata);
			pdfdata.close();

			PDFParser p = new PDFParser(new ByteArrayInputStream(pdfdata.toByteArray()));
			p.parse();

			PDDocument doc = new PDDocument(p.getDocument());
			PDDocumentInformation info = doc.getDocumentInformation();

			info.setAuthor("Author");
			info.setKeywords("Keywords");
			info.setTitle("Title");
			info.setTrapped("False");
			info.setCustomMetadataValue("", "");
			info.setCreator("Creator");
			info.setSubject("Subject");
			info.setProducer("Producer");
			doc.setDocumentInformation(info);

			doc.save(resp.getOutputStream());
			doc.close();

		} catch (Exception e) {
			e.printStackTrace();
			resp.setContentType("text/plain");
			e.printStackTrace(resp.getWriter());
		}
	}

}
```


----------

