2012-07-24 14 views
7

Nella mia pipeline di produzione ho bisogno di generare alcune centinaia di PDF da HTML. Per questo scenario, prima converto l'HTML in XHTML. Di non passare l'XHTML 'pulito' e l'uri al renderer.XHTML in PDF utilizzando il disco volante come cache css

Poiché i file * .css e imageFiles sono uguali per tutti i file XHTML, non è necessario risolverli per tutto il tempo in cui elabora un file. Im utilizzando correttamente il seguente codice per la memorizzazione nella cache delle immagini. Come posso archiviare anche i file .css? Voglio evitare di mettere tutti i file nel mio classpath.

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; 
    } 
} 

risposta

3

in cui qualcuno che si trova ad affrontare lo stesso problema qui è come l'ho risolto. Poiché non ero in grado di memorizzare nella cache i file * .css all'interno di CustomUserAgent, dovevo trovare un altro modo. La mia soluzione utilizza Squid come proxy http per memorizzare nella cache tutte le risorse utilizzate di frequente.

All'interno di CustomUserAgent, devo solo accedere a questo proxy passando l'oggetto 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; 
} 
} 

cache:

resolving css took 74 ms 
resolving images took 225 ms 

non memorizzata nella cache:

resolving css took 15466 ms 
resolving images took 11236 ms 

come si può vedere, i differenti tra risorse memorizzate nella cache e non memorizzati nella cache sono significativi

Problemi correlati