Восстановление защищенных ресурсов с помощью Flying Saucer (ITextRenderer) - PullRequest
6 голосов
/ 24 января 2011

Я использую Flying Saucer для создания PDF-файла из xhtml, размещенного на сервере Tomcat.Большинство изображений, включенных в pdf, являются общедоступными (логотипы и т. Д.), Но некоторые из них защищены за входом в систему (то есть они передаются через сервлет, если пользователь вошел в систему).

Когда я вставляю URL в браузер, изображение, конечно, отображается нормально, потому что браузер отправляет сеанс с запросом.Но когда «Летающая тарелка» отображает PDF-файл, он не включает защищенное изображение, потому что ничего не знает о сеансе.

Итак, мой вопрос:есть ли способ включить потоки байтов для разрешения Flying Saucer, так же как можно добавить разрешаемые шрифты?Я пробовал что-то вроде this , но нет простого способа установить UAC на ITextRenderer, и он жаловался каждый раз, когда я пытался.

Ответы [ 2 ]

6 голосов
/ 18 февраля 2011

Вы можете установить UserAgentCallback таким образом, и Flying Saucer будет использовать его для разрешения URL (протестировано, работает с версией 8):

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

MyUAC должен расширить NaiveUserAgent и переопределить метод resolveAndOpenStream, как предлагает другая страница.

2 голосов
/ 19 марта 2012

Я также переопределил 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?
    }
}
...