Navigation from managed bean constructor in ADF Faces JSF 1.2

落爺英雄遲暮 提交于 2019-12-05 15:23:04

It's easier to solve a problem if the cause of the problem is understood. A good exception tells basically already everything about the cause of the problem.

Look closer:

java.lang.IllegalStateException: Cannot forward after response has been committed

The response has been committed. This is a point of no return. Perhaps you failed to understand what it means that a response has been committed (which has the consequence that you also failed to understand the exception itself).

By default, the HTTP response is written to a buffer which is flushed every ~2KB, depending on server configuration. A flush of the response buffer causes the written bytes being actually sent from server to client. Once that happens for the first time, a response is considered committed. This is a point of no return. The server cannot take the already written bytes back from the client in case the server actually needs to change the response afterwards.

If you have some code which potentially needs to change the response, then you should be invoking it before the response is committed.

In your particular case, the managed bean is apparently constructed in the midst of the JSF render response phase during generating the HTML output. A part of the generated HTML output has already been sent to the client (so, the response is committed). You're apparently referencing the request scoped bean relatively late in the JSF page, or the response buffer is relatively small, or the HTML <head> is relatively large which causes a flush already before the <body> starts, etcetera.

You really need to invoke the code before the render response phase. In JSF 1.2, you can use the <f:view beforePhase> for this.

E.g.

<f:view beforePhase="#{bean.navigate}">

with

public void navigate(PhaseEvent event) {
    if (event.getPhaseId() == PhaseId.RENDER_RESPONSE) {
        // Do here your job which should run right before the RENDER_RESPONSE.
    }
}

Then your Try-1 and Try-3 will work (you can however leave those responseComplete() and renderResponse() lines away, they are implicitly already taken care of).

Try-2 and Try-4 are poor. You should avoid having javax.servlet.* imports in your backing bean. Try-5 is clumsy. Try-6, Try-7 and Try-8 are beyond my scope. Try-9 is doable, but extremely clumsy.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!