[coldbox-3.5.2] OutputStream Help (I think)

I’m attempting to implement the Batik library into my app in order to render the SVG taken from charts created with ExtJS into PNG images (e.g., view a chart, and then download an image of it). For the Batik integration, I’m following the example found here, and I’ve verified that it works. Here’s what my code looks like so far:

public void function makeImage( required string svg ) {
var pc = getPageContext();

pc.setFlushOutput( false );
var transcoder = createObject( “java”, “org.apache.batik.transcoder.image.PNGTranscoder” ).init();

// set content type for response

pc.getResponse().getResponse().setContentType( ‘image/*’ );

// set the right header to download the file from the browser

pc.getResponse().setHeader( “Content-Disposition”, “inline; filename=myfile.png” );

var inputStream = createObject( “java”, “java.io.StringBufferInputStream” ).init( svg );

var input = createObject( “java”, “org.apache.batik.transcoder.TranscoderInput” ).init( inputStream );

var outputStream = pc.getResponse().getResponse().getOutputStream();

var output = createObject( “java”, “org.apache.batik.transcoder.TranscoderOutput” ).init( outputStream );

transcoder.transcode(input, output);

outputStream.flush();

outputStream.close();

}

The problem I’m running into, however, is when I try to integrate this with ColdBox. If I make the method remote, and simply post the SVG to the method (e.g., handlers/mycfc.cfc?method=makeImage), it works exactly as I would expect it to (a png image is downloaded). However, if I call this method via a handler (or even put the guts of the method in a handler, for that matter), it downloads the file as before, but devoid of content (a blank image).

I assume the issue is with how the Batik library is handling the outputstream in the transcode() method, but don’t really know where to begin to debug this. I appreciate any insights/ideas that anyone might have regarding this.

Thanks!

Well, you are talking to the output response of the page context directly. So if you do a handler then it is trying to output something as well.

I would suggest you add something like event.noRender() in your handler so ColdBox does not render anything and your code just executes.

signature0.jpg

Luis F. Majano
CEO
Ortus Solutions, Corp
www.ortussolutions.com

ColdBox Platform: http://www.coldbox.org
Linked In: http://www.linkedin.com/pub/3/731/483
Blog: http://www.luismajano.com
IECFUG Manager: http://www.iecfug.com

Social: twitter.com/lmajano facebook.com/lmajano

Hi Luis–

Thanks for the response. I tried event.noRender(), but unforunately I get the same issue. Any other ideas?

Thanks

Hi Joel,

I did similar something you are trying.
Important bit is to terminate the reset of process “abort”

------------EVENT HANDLER ACTION------------------------------------------------

function getResizedImage(event,rc,prc){
var path = “/” & Replace(rc.path, “-”, “/”, “All”) & “/” & rc.img;

var filePath = ImageService.getResizedImagePath(imagePath=path, width=rc.w, height=rc.h, resizeMethod=“scaleAndCrop”);

// This is how you get a file as a binary stream
var fileBytes = fileReadBinary( ExpandPath(filePath) );

// get the http response
if ( server.coldfusion.productname eq “Railo” ){
var response = getPageContext().getResponse();
// set the appropriate mime type
response.setHeader( ‘Content-Type’, ‘image/#ListLast(rc.img, “.”)#’ );

// replace the output stream contents with the binary
response.getOutputStream().write( fileBytes );
response.getOutputStream().close();
}else{
var response = getPageContext().getFusionContext().getResponse();
// set the appropriate mime type
response.setHeader( ‘Content-Type’, ‘image/#ListLast(rc.img, “.”)#’ );
// replace the output stream contents with the binary
response.getOutputStream().writeThrough( fileBytes );
}

// leave immediately to ensure now whitespace is added
abort;
}

Hi Sana–

Thanks for the response. I was already aborting, but the part of your code that actually resolved the issue for me was the var response = getPageContext().getFusionContext().getResponse();

Switching getPageContext.getResponse() to getPageContext.getFusionContext() did the trick (I’d love to know why, if anyone can illuminate me).

Thanks!

Here’s the snippet that’s now working:

`

var pc = getPageContext();
pc.setFlushOutput( false );
var transcoder = createObject( “java”, “org.apache.batik.transcoder.image.PNGTranscoder” ).init();
// set content type for response
pc.getResponse().getResponse().setContentType( ‘image/*’ );
// set the right header to download the file from the browser
pc.getResponse().setHeader( “Content-Disposition”, “inline; filename=myfile.png” );
var inputStream = createObject( “java”, “java.io.StringBufferInputStream” ).init( svg );
var input = createObject( “java”, “org.apache.batik.transcoder.TranscoderInput” ).init( inputStream );
var outputStream = pc.getFusionContext().getResponse().getOutputStream();
var output = createObject( “java”, “org.apache.batik.transcoder.TranscoderOutput” ).init( outputStream );
transcoder.transcode(input, output);
outputStream.flush();
outputStream.close();

`