2012-07-24 58 views
7

W moim strumieniu produkcji muszę wygenerować kilkaset plików PDF z HTML. W tym scenariuszu najpierw konwertuję HTML na XHTML. Niż ich przekazanie "wyczyszczone" XHTML i URI do renderera.XHTML do PDF za pomocą latającego spodka, jak cache css

Ponieważ pliki * .css i imageFiles są równe dla wszystkich plików XHTML, nie muszę ich rozwiązywać przez cały czas przetwarzania pliku. Pomyślnie za pomocą następującego kodu dla buforowania obrazów. Jak mogę buforować pliki .css? Chcę uniknąć umieszczania wszystkich plików w mojej ścieżce klas.

ITextRenderer renderer = new ITextRenderer(); 

ResourceLoaderUserAgent callback = new ResourceLoaderUserAgent(renderer.getOutputDevice()); 
callback.setSharedContext(renderer.getSharedContext()); 

for (MyObject myObject : myObjectList) { 

    OutputStream os = new FileOutputStream(tempFile); 

    final DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); 
    documentBuilderFactory.setValidating(false); 
    DocumentBuilder builder = documentBuilderFactory.newDocumentBuilder(); 
    org.w3c.dom.Document document = builder.parse(myObject.getLocalPath); // full path to .xhtml 

    renderer.getSharedContext().setUserAgentCallback(callback); 

    renderer.setDocument(document, myObject.getUri()); 
    renderer.layout(); 
    renderer.createPDF(os); 

    os.flush(); 
    os.close(); 
} 
    ... 


private static class ResourceLoaderUserAgent extends ITextUserAgent 
{ 
    public ResourceLoaderUserAgent(ITextOutputDevice outputDevice) { 
     super(outputDevice); 
    } 

    protected InputStream resolveAndOpenStream(String uri) { 
     InputStream is = super.resolveAndOpenStream(uri); 
     System.out.println("IN resolveAndOpenStream() " + uri); 

     return is; 
    } 
} 

Odpowiedz

3

Przykryć kogoś stojącego przed tym samym problemem Oto jak go rozwiązałem. Ponieważ nie mogłem buforować plików * .css w mojej CustomUserAgent, musiałem znaleźć inny sposób. Moje rozwiązanie używa Squid jako http-proxy do buforowania wszystkich często używanych zasobów.

Wewnątrz mojej CustomUserAgent muszę tylko uzyskać dostęp do tego proxy, przekazując obiekt proxy.

public class ResourceLoaderUserAgent extends ITextUserAgent { 

public ResourceLoaderUserAgent(ITextOutputDevice outputDevice) { 
    super(outputDevice); 
} 

protected InputStream resolveAndOpenStream(String uri) {  

    HttpURLConnection connection = null; 
    URL proxyUrl = null; 
    try { 
     Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("localhost", 3128)); 
     proxyUrl = new URL(uri); 
     connection = (HttpURLConnection) proxyUrl.openConnection(proxy); 
     connection.connect(); 

    } catch (Exception e) { 
     throw new RuntimeException(e); 
    } 

    java.io.InputStream is = null; 
    try { 
     is = connection.getInputStream(); 
    } catch (java.net.MalformedURLException e) { 
     XRLog.exception("bad URL given: " + uri, e); 
    } catch (java.io.FileNotFoundException e) { 
     XRLog.exception("item at URI " + uri + " not found"); 
    } catch (java.io.IOException e) { 
     XRLog.exception("IO problem for " + uri, e); 
    } 

    return is; 
} 
} 

buforowane:

resolving css took 74 ms 
resolving images took 225 ms 

niebuforowanych:

resolving css took 15466 ms 
resolving images took 11236 ms 

jak widać, differents między buforowanych i niebuforowanych zasobów są znaczące

Powiązane problemy