2011-01-24 16 views
6

Estoy utilizando Flying Saucer para crear un pdf desde xhtml, alojado en un servidor tomcat. La mayoría de las imágenes incluidas en el pdf están a disposición del público (logotipos, etc.), pero algunas están protegidas por un inicio de sesión (es decir, se transmiten a través de un servlet si el usuario está conectado).Resolviendo recursos protegidos con Flying Saucer (ITextRenderer)

Cuando pego la url en el navegador, la imagen, por supuesto, se muestra bien, porque el navegador envía la sesión con la solicitud. Pero cuando Flying Saucer representa el pdf, no incluye la imagen protegida porque no sabe nada sobre la sesión.

Entonces, mi pregunta es; ¿Hay alguna manera de resolver las secuencias de bytes para resolver Flying Saucer, del mismo modo que es posible agregar fuentes resolubles? He intentado algo como this, pero no hay una manera fácil de configurar el UAC en ITextRenderer, y se quejaba cada vez que lo intentaba.

Respuesta

6

Puede configurar el UserAgentCallback esta manera, y platillo volante va a usar para resolver las direcciones URL (probado, funciona de la Versión 8):

ITextRenderer renderer = new ITextRenderer(); 
renderer.getSharedContext().setUserAgentCallback(new MyUAC()); 

MyUAC debería ampliar el NaiveUserAgent, y reemplazar el método resolveAndOpenStream como la otra página sugiere.

+1

Gracias, esto funcionó para mí, aunque me ampliado la clase ITextUserAgent en lugar. – ManiSto

+0

@ManiSto Me estoy enfrentando al problema exacto que enfrentaste. ¿Podría darme algún código de muestra sobre cómo implementó MyUAC()? –

2

Ignore ITextUserAgent también - desde la fuente, parece que eso es lo que usa ITextRenderer. Debe proporcionar el dispositivo de salida en el constructor, que puede obtener del objeto procesador. Otro inconveniente es que debe establecer explícitamente el "contexto compartido" utilizando el método setter; de lo contrario, obtendrá un NPE durante la representación. Aquí está el código para configurar el objeto:

ITextRenderer renderer = new ITextRenderer(); 
MyUserAgentCallback uac = new MyUserAgentCallback(renderer.getOutputDevice()); 
uac.setSharedContext(renderer.getSharedContext()); 
renderer.getSharedContext().setUserAgentCallback(uac); 

Además, aquí es la idea básica de MyUserAgentCallback, mediante la autenticación básica:

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

    @Override 
    protected InputStream resolveAndOpenStream(String uri) 
    { 
     if (_isProtectedResource(uri)) 
     { 
      java.io.InputStream is = null; 
      uri = resolveURI(uri); 
      try { 
       URL url = new URL(uri); 
       String encoding = new BASE64Encoder().encode ("username:password".getBytes()); 
       URLConnection uc = url.openConnection(); 
       uc.setRequestProperty ("Authorization", "Basic " + encoding); 
       is = uc.getInputStream(); 
       Log.debug("got input stream"); 
      } 
      catch (java.net.MalformedURLException e) { 
       Log.error("bad URL given: " + uri, e); 
      } 
      catch (java.io.FileNotFoundException e) { 
       Log.error("item at URI " + uri + " not found"); 
      } 
      catch (java.io.IOException e) { 
       Log.error("IO problem for " + uri, e); 
      } 
      return is; 
     } 
     else 
     { 
      return super.resolveAndOpenStream(uri); 
     } 
    } 

    private boolean _isProtectedResource(String uri) 
    { 
     // does this require authentication? 
    } 
} 
Cuestiones relacionadas