Finally, I've managed to dig through the XHtmlRenderer's code, and the IText
dependencies inside, and have encountered the root of the issue :
The problem is raised by the IText Image resource class, which tries to
detect the format of the image by peeking at the first bytes of the stream.
Getting into details, that piece of code receives an InputStream, obtained
from a "new URL(source)", where 'source' is the value of the 'src' attribute
in the <img> tag.
I've tried constructing that URL by myself, and peeking at the first bytes,
and have found that they do not match what it should be expected taking into
account the image's format (jpg -> 0xFF, 0xD8). Instead, the first bytes
are: 0x3C, 0x21, 0x44, 0x4F.
I'm creating the Wicket image resource with a DynamicImageResource, and I've
checked that, when it's called, it returns the expected first bytes...
DynamicImageResource resource = new DynamicImageResource("jpg") {
@Override
protected byte[] getImageData() {
return generateBarCode(....);
}
};
And again, when I try this on the link's onClick:
link = new Link("printFullPagament"){
private static final long serialVersionUID = 1L;
@Override
public void onClick() {
try{
String srcImg = "
http://myapp/?wicket:interface=:34:
barcode::IResourceListener::&wicket:antiCache=1274953227999";
java.io.InputStream is = new
URL(srcImg).openStream();
int c1 = is.read();
int c2 = is.read();
int c3 = is.read();
int c4 = is.read();
...
}
I don't seem to get DynamicImageResource#getImageData, nor any of the
methods it defines (getResourceState()), and get those values on the first
bytes ( 0x3C, 0x21, 0x44, 0x4F)
Does anyone know what may be happening here ?
Thanks a lot,
Xavier Lopez
2010/5/27 Xavier López <[email protected]>
> Sorry for double-posting, I'm attaching some of the code I'm using:
>
> I havent't mentioned other static styling images are rendering correctly.
>
>
> byte[] imageByteArray = generateBarCodeImage(...)
>> ByteArrayResource resource = new ByteArrayResource("image/jpeg",
>> imageByteArray);
>> Image barcodeImage= new Image("barcode", resource){
>> protected void onComponentTag(ComponentTag tag)
>> {
>> super.onComponentTag(tag);
>> String url = tag.getAttributes().getString("src");
>> url = url + ((url.indexOf("?") >= 0) ? "&" : "?");
>> url = url + "wicket:antiCache=" +
>> System.currentTimeMillis();
>> tag.put("src", url);
>> }
>> };
>> barcodeImage.setMarkupId("barcodeImageId");
>> barcodeImage.setOutputMarkupId(true);
>> add(imatgeCodiBarres);
>> .....
>> link = new Link("printPDF"){
>> private static final long serialVersionUID = 1L;
>> @Override
>> public void onClick() {
>> try{
>> String baseUrl = "http://myapp/";
>> // Get the html to render into pdf
>> String html = RenderHTMLUtils.renderPage(new
>> PrintPage(...));
>> DocumentBuilder builder =
>> DocumentBuilderFactory.newInstance().newDocumentBuilder();
>> Document doc = builder.parse(new
>> ByteArrayInputStream(html.getBytes("UTF-8")));
>>
>>
>> String src =
>> doc.getElementById("barcodeImageId").getAttribute("src");
>> src = baseUrl + src;
>>
>> doc.getElementById("barcodeImageId").setAttribute("src", src);
>>
>> ITextRenderer renderer = new ITextRenderer();
>> renderer.setDocument(doc, baseUrl);
>>
>>
>> RequestCycle.get().setRequestTarget(EmptyRequestTarget.getInstance());
>> WebResponse response = (WebResponse)
>> getResponse();
>> response.setContentType("application/pdf");
>> response.setAttachmentHeader("printout.pdf");
>> response.setHeader("Cache-Control",
>> "max-age=0");
>> OutputStream out = response.getOutputStream();
>> renderer.layout();
>> renderer.createPDF(out);
>> }
>> catch (Exception e){ }
>> }
>> };
>>
>
> 2010/5/27 Xavier López <[email protected]>
>
> Hi,
>>
>> I'm trying to use a xhtml to pdf renderer
>> (https://xhtmlrenderer.dev.<http://goog_1283895835>
>> java.net/) in order to print out a page to PDF.
>>
>> The page contains a NonCachingImage, with a barcode, in such a way that
>> the image gets the following HTML :
>>
>> <?xml version="1.0" encoding="UTF-8"?>
>>> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "
>>> http://www.w3.org/TR/xhtml11/DTD/xhtml11-flat.dtd">
>>> <html xml:lang="ca" xmlns="http://www.w3.org/1999/xhtml">
>>> ...
>>> <img class="floatR"
>>> src="?wicket:interface=:34:barcode::IResourceListener::&wicket:antiCache=1274953227999"/>
>>> ...
>>> </html>
>>>
>>
>> When parsing the html String into a org.w3c.dom.document, I get the
>> following exception:
>>
>> org.xml.sax.SAXParseException: The reference to entity "wicket:antiCache"
>>> must end with the ';' delimiter.
>>>
>>
>>
>> I know this is probably not a Wicket issue, and maybe has to do with the
>> DTD used for validation, or something like that.
>> I found somewhere this can get solved by changing the '&' character in the
>> URL by '&'. That worked. Now I plan to override NonCachingImage's
>> onComponentTag to append & instead of '&'.
>>
>> That solved, I can't get the image to get rendered in the pdf document, in
>> the html's DOM I have the <img> Element with the 'src' atttribute with value
>> ="http://myapp/?wicket:interface=:34:
>> barcode::IResourceListener::&wicket:antiCache=1274953227999", but
>> Image#onResourceRequested() (which is the callback for that URL) never gets
>> called during the render phase of the PDF...
>>
>> I'd really appreciate any hints on this one, I've been looking into the
>> resources reference but I don't know if I should use it, or which
>> implementation to use... The image resource is formed from a byte array.
>>
>> Many thanks,
>> Xavier López
>>
>
>