Wednesday, 31 August 2022

CFML: outputting text from within inline Java in CFML

G'day:

I saw an odd question today. Me mate Ray was messing around with the Java integration in ColdFusion (that allows one to write Java code directly in one's CFML code), and asked how to write out content to the screen from within the Java code. IE: the equiv of emiting some text in one's CFML response… it ends up on the client browser "screen" (this is not my wording).

My initial reaction was "isn't the answer System.out.println("G'day Ray!")?". But it's not. System.out writes to stdout. Not the response buffer. In my Docker container if I do that println, I get it in my Docker log, eg:

OK so it's not a dumb question.

I knew the answer would be "stick it in the PageContext's BodyContent", but I had no idea of how to get a reference to that via Java. Especially basically a Java snippet running inside a ColdFusion request. I googled a lot and did not find anything I understood (my Java is shit).

So I cheated. ColdFusion knows how to get the current PageContext: via getPageContext(). I'll just pass that in to my Java code:

Warning

This code runs fine in the version of CF that is installed from the adobecoldfusion/coldfusion2021:latest Docker image, but does not run on a local install of CF (even the "exact same version"). It will give you a The setPageContext method was not found. error. I'm not sure why, but I managed to grab the ear of one of the Adobe bods, and they are actively looking into it. I'll report back when we get an answer on this.

messager = java {

    import javax.servlet.jsp.PageContext;

    public class Outputer {

        PageContext pageContext;

        public void output(String text) throws java.io.IOException {
            this.pageContext.getOut().print(text);
        }

        public void setPageContext(PageContext pageContext) {
            this.pageContext = pageContext;
        }
    }
}

messager.setPageContext(getPageContext())
writeOutput("Before stuff added from Java<br>")
messager.output("G'day Ray!<br>")
writeOutput("After stuff added from Java<br>")

And this works:

Before stuff added from Java
G'day Ray!
After stuff added from Java

I dunno if it's a good way of doing it, but it's "a" way.

I'd still prefer knowing how to get the PageContext directly from the Java code, if anyone knows…?

Righto.

--
Adam