6

我正在使用 Flying Saucer 从 xhtml 创建一个 pdf,托管在 tomcat 服务器上。pdf 中包含的大多数图像都是公开可用的(徽标等),但其中一些在登录后受到保护(也就是说,如果用户登录,它们会通过 servlet 流式传输)。

当我将 url 粘贴到浏览器中时,图像当然可以正常显示,因为浏览器会发送带有请求的会话。但是当 Flying Saucer 渲染 pdf 时,它不包含受保护的图像,因为它对会话一无所知。

所以,我的问题是;有什么方法可以包含飞碟解析的字节流,就像可以添加可解析的字体一样?我已经尝试过类似的方法,但是没有简单的方法可以在 ITextRenderer 上设置 UAC,并且每次尝试时都会抱怨。

4

2 回答 2

7

您可以通过这种方式设置 UserAgentCallback,Flying Saucer 将使用它来解析 url(经过测试,适用于 Release 8):

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

MyUAC 应该扩展, 并按照其他页面的建议NaiveUserAgent覆盖该方法。resolveAndOpenStream

于 2011-02-18T17:43:42.553 回答
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?
    }
}
于 2012-03-19T14:37:59.620 回答