Java – rendering images from servlets in PDF generated by flyingsaucer
I'm using flyingsaucer to render the XHTML document to pdf.pdf through a servlet that returns the generated PDF document The XHTML document has an image requested from another servlet The image servlet checks who returns the appropriate image before logging in The following code shows how to request an image:
<img height="140" width="140" src="http://localhost:8080/myapp/servlet/DisplayPic" />
My problem is that the HTTP request for the image comes from the PDF renderer, not the logged in user, so the image servlet does not know who logged in, so it will not return the required image
I am using the following code to render an XHTML document:
ITextRenderer renderer = new ITextRenderer(); renderer.setDocumentFromString(xhtmlDocumentAsString); renderer.layout(); os = response.getOutputStream(); renderer.createPDF(os);
I need to maintain the user's session when requesting an image servlet, or provide the renderer with an image to use for that particular XHTML element I think the latter can be done using replacedelementfactory, but I can't mine any sample code that can help me
Solution
I have a very good job now This is the code
In my XHTML document, I have:
<div class="profile_picture" style="display:block;width:140px;height:140px;" />
(I use div elements instead of img, because factories are only used for block level elements)
I use:
ITextRenderer renderer = new ITextRenderer(); renderer.getSharedContext().setReplacedElementFactory(new ProfileImageReplacedElementFactory(renderer.getSharedContext().getReplacedElementFactory())); renderer.setDocumentFromString(xhtmlDocumentAsString); renderer.layout(); os = response.getOutputStream(); renderer.createPDF(os);
I have my own replacedelementfactory as follows:
public class ProfileImageReplacedElementFactory implements ReplacedElementFactory { private final ReplacedElementFactory superFactory; public ProfileImageReplacedElementFactory(ReplacedElementFactory superFactory) { this.superFactory = superFactory; } @Override public ReplacedElement createReplacedElement(LayoutContext layoutContext,Block@R_449_2419@ block@R_449_2419@,UserAgentCallback userAgentCallback,int cssWidth,int cssHeight) { Element element = block@R_449_2419@.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,block@R_449_2419@,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); } }