Рендеринг изображения из сервлета в созданном flyingsaucer pdf
Я использую flyingsaucer для рендеринга xhtml-документа в pdf через сервлет, который возвращает сгенерированный pdf-документ. В документе xhtml имеется изображение, запрашиваемое у другого сервлета. Сервлет изображения проверяет, кто вошел в систему, прежде чем вернуть соответствующее изображение. Код ниже показывает, как запрашивается изображение:
<img height="140" width="140" src="http://localhost:8080/myapp/servlet/DisplayPic" />
Моя проблема в том, что http-запрос на изображение от pdf рендера, а не вошедшего в систему пользователя, поэтому сервлет изображения не знает, кто вошел в систему, и, следовательно, нужное изображение не возвращается.
В настоящее время я использую приведенный ниже код для рендеринга документа xhtml:
ITextRenderer renderer = new ITextRenderer();
renderer.setDocumentFromString(xhtmlDocumentAsString);
renderer.layout();
os = response.getOutputStream();
renderer.createPDF(os);
Мне нужно либо поддерживать сеанс пользователя, когда запрашивается сервлет изображения, либо предоставлять рендереру изображение, которое будет использоваться для этого конкретного элемента xhtml. Я думаю, что последнее может быть сделано с помощью ReplacedElementFactory
но я не смог найти ни одного примера кода, который мог бы мне помочь.
1 ответ
У меня это работает очень хорошо сейчас. Вот код
В моем документе HTML я имею:
<div class="profile_picture" style="display:block;width:140px;height:140px;" />
(Я использую div
элемент вместо img
так как фабрика используется только для элементов блочного уровня)
Я отображаю свой документ, используя:
ITextRenderer renderer = new ITextRenderer();
renderer.getSharedContext().setReplacedElementFactory(new ProfileImageReplacedElementFactory(renderer.getSharedContext().getReplacedElementFactory()));
renderer.setDocumentFromString(xhtmlDocumentAsString);
renderer.layout();
os = response.getOutputStream();
renderer.createPDF(os);
И у меня есть свой ReplacedElementFactory
как показано ниже:
public class ProfileImageReplacedElementFactory implements ReplacedElementFactory {
private final ReplacedElementFactory superFactory;
public ProfileImageReplacedElementFactory(ReplacedElementFactory superFactory) {
this.superFactory = superFactory;
}
@Override
public ReplacedElement createReplacedElement(LayoutContext layoutContext, BlockBox blockBox,
UserAgentCallback userAgentCallback, int cssWidth, int cssHeight) {
Element element = blockBox.getElement();
if (element == null) {
return null;
}
String nodeName = element.getNodeName();
String className = element.getAttribute("class");
if ("div".equals(nodeName) && className.contains("profile_picture")) {
InputStream input = null;
try {
input = ...;
byte[] bytes = IOUtils.toByteArray(input);
Image image = Image.getInstance(bytes);
FSImage fsImage = new ITextFSImage(image);
if (fsImage != null) {
if ((cssWidth != -1) || (cssHeight != -1)) {
fsImage.scale(cssWidth, cssHeight);
}
return new ITextImageElement(fsImage);
}
} catch (IOException e) {
getLogger().error(ExceptionUtils.getStackTrace(e));
} catch (BadElementException e) {
getLogger().error(ExceptionUtils.getStackTrace(e));
} finally {
IOUtils.closeQuietly(input);
}
}
return superFactory.createReplacedElement(layoutContext, blockBox, userAgentCallback, cssWidth, cssHeight);
}
@Override
public void reset() {
superFactory.reset();
}
@Override
public void remove(Element e) {
superFactory.remove(e);
}
@Override
public void setFormSubmissionListener(FormSubmissionListener listener) {
superFactory.setFormSubmissionListener(listener);
}
}