2011-01-24 67 views
6

我使用Flying Saucer從xhtml創建PDF,託管在tomcat服務器上。 PDF中包含的大多數圖像都是公開可用的(徽標等),但其中一些圖像在登錄後受保護(即,如果用戶已登錄,則通過servlet進行流式傳輸)。使用飛碟解決受保護的資源(ITextRenderer)

當我將url粘貼到瀏覽器中時,圖片當然顯示正常,因爲瀏覽器會發送會話請求。但是,當Flying Saucer呈現pdf時,它不包含受保護的圖像,因爲它不知道會話的任何內容。

所以,我的問題是;是否有任何方法可以包含飛碟的字節流來解決,就像添加可解析的字體一樣?我試過類似this的東西,但是沒有簡單的方法在ITextRenderer上設置UAC,每當我嘗試時都會抱怨。

回答

6

您可以設置UserAgentCallback這種方式,和飛碟將使用它來解析URL(經測試,可與第8版):

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

MyUAC應延長NaiveUserAgent,並重寫resolveAndOpenStream方法另一頁顯示。

+1

謝謝,這個工作對我來說,雖然我延長了ITextUserAgent類代替。 – ManiSto 2011-02-22 12:22:08

2

我也覆蓋了ITextUserAgent - 從源代碼看起來就像ITextRenderer使用的那樣。您必須在構造函數中提供輸出設備,您可以從渲染器對象獲取輸出設備。另一個問題是你必須使用setter方法明確地設置「共享上下文」 - 否則在渲染過程中你會得到一個NPE。這是建立在對象的代碼:

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

而且,這裏是MyUserAgentCallback的基本思想,使用基本身份驗證:

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