XPages and Java

Simply put:

facesContext.getResponseStream() returns null.

facesContext.getReponse().getOutputStream() throws the following exception:

java.lang.IllegalStateException: Can’t get an OutputStream while a Writer is already in use

So I cannot see any way of getting an Stream rather than a Writer.

I was trying to get Ed Wissels technique to work to allow xpages to return binary as this is something I would dearly like to have for my current project. I can’t see how it’s possible.

I also have a problem with any xpage Java placed in WebContent/WEB_INF being cached permanently and needing a server restart.

Anyone have any experience with the ResponseStream objects? The ResponseWriter works fine but handles only text.

No love for xpages yet!

S

EDIT: I am using this code in the afterRenderReponse event.

var rs = facesContext.getResponseStream();

var rw = facesContext.getResponseWriter();

if(rs == null ) {

rw.write("stream == null");

} else {

rw.write("we have a stream");

}

Always outputs stream == null

Sounds to me like the xpage system is always instantiating the PrintWriter object even when all rendering is turned off and this blocks any attempt at getting at the OutputStream.

I have tried closing/flushing/ending/null’ing the ResponseWriter object, but nothing seems to work.

Subject: I don’t think you can get both a writer and a stream at the same time

Hi Simon,

Have you found a solution yet?

I’m not sure, but I believe that I somewhere read that you can’t get both a writer and a stream at the same time. You have to choose, so maybe you should try the following code instead:

if (IWantAWriter == true) {

var rw = facesContext.getResponseWriter();

rw.write(“We have a writer”);

} else {

var rs = facesContext.getResponseStream();

rs.write(“We have a stream”);

}

Subject: No joy

Hi Andrew

Yeah that’s true, but I tried to get the ResponseStream first so getResponseWriter() should have failed. It’s just there to print out the message, normally it wouldn’t be there.

getResponseStream() always returns null, if you try and use it, you just get a null pointer exception.

I have also tried accessing it via Java, same deal. I don’t think they support ResponseStreams at all.

S

Subject: It’s sad

It’s sad to see how much posibilities lies in XPages, but with so little documentation and examples comming out of IBM.

I’ve also tried to ask a question to a wiki-article, but it seems noone monitors these comments. See http://www-10.lotus.com/ldd/ddwiki.nsf/dx/xpages-cgi-variables.htm

Subject: Agreed

Some of the magic answers coming out of blogs imply the existence of knowledge that I can’t find documented anywhere.

Stephan Wissel kindly noted that you cannot get the stream at all in the afterRender event, as the Domino server will have automatically enabled the Writer, and as you can only have EITHER stream OR writer active, streams are not available in the afterRender event.

I am continuing the hunt though by checking other events =)

  1. No getResponseStream()

First test seems to show that facesContext.getResponseStream() has not been implemented at all.

I tried the following fragment in all events, one at a time.

print(“start”);

var rs = facesContext.getResponseStream();

if(rs == null) {

print(“fc.getResponseStream() == null”);

} else {

print(rs.getClass().getName());

}

print(“end”)

This prints fce.getResponseStream() == null, in all events. I don’t know if this is broken or ‘working as intended’

  1. Getting output stream from the Response object breaks the xpage.

print(“start”);

var ex = facesContext.getExternalContext();

var response = ex.getResponse();

var rs = response.getOutputStream();

if(rs == null) {

print(“response.getOutputStream() == null”);

} else {

print(rs.getClass().getName());

}

print(“end”)

As you predicted, the getOutputStream() fails on the afterRenderResponse() event. On all other events I see the following:

10/05/2009 19:02:25 HTTP JVM: start

10/05/2009 19:02:25 HTTP JVM: com.ibm.xsp.webapp.XspHttpServletResponse$InternalOutputStream

10/05/2009 19:02:25 HTTP JVM: end

10/05/2009 19:02:25 HTTP JVM: SEVERE: CLFAD####E: Exception thrown

10/05/2009 19:02:25 HTTP JVM: SEVERE: CLFAD####E: Exception occurred servicing request for: /test/TestCharts.nsf/test.xsp - HTTP Code: 500

10/05/2009 19:02:25 HTTP Web Server: Command Not Handled Exception [/test/TestCharts.nsf/test.xsp]

My current theory?

The Domino server expects to get access to the Writer object, if you access the Stream object the Writer is disabled and when Domino tries to get it, instead of failing gracefully, it croaks and sends a 500 response.

There may be a magic call to stop Domino doing that but there’s no doco. I will hunt through JSF stuff maybe.

S

Subject: In case this isn’t totally buried…

I spent a bit of time with JSF doco last night, and one thing stuck in my mind.

The beforeRenderResponse and afterRenderResponse are parts of the JSF ‘lifecycle’. My theory was that the last part of the lifecycle was crashing when Domino found someone had blocked it getting a Writer.

So if I stopped it moving on to that phase, I could maybe fix it.

Cue facesContext.responseComplete() which signals to JSF to stop the lifecycle. This fixed the last problem and now I can send binary to the browser.

Trouble is, Domino seems to be screwing up my Content-Length header. I set the length of the binary data, but when I check in the browser, the figure has been changed and is now wrong.

Will post if I can sort this out

S

Subject: Have you a solution?

HiI also want to return a stream (image) from an x-page.

Where did you put your code? And how helped “facesContext.responseComplete()”?

Maybe in some way we can get this to work…

/Tobias

I found the soluntion for me:

http://www.wissel.net/blog/d6plinks/SHWL-8248MT