且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

从ADF Faces JSF 1.2中的托管bean构造函数导航

更新时间:2023-10-10 21:57:34

如果理解问题的原因,解决问题更容易。一个很好的例外基本上就是说明问题的原因。

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.

看看更近:


java.lang.IllegalStateException:响应提交后无法转发

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).

默认情况下,HTTP响应写入缓冲区,每个〜2KB刷新,取决于服务器配置。响应缓冲区的刷新将导致实际从服务器发送到客户端的写入字节。一旦发生这种情况,应答就被认为是承诺的。这是一个不回报的点。服务器无法从客户端返回已经写入的字节,以防服务器实际需要稍后更改响应。

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.

在特定情况下,在生成HTML输出期间,受管Bean显然是在JSF渲染响应阶段中构建的。生成的HTML输出的一部分已经发送到客户端(因此,响应已提交)。您显然是在JSF页面中引用了请求作用域bean,或者响应缓冲区相对较小,或者HTML < head> 相对较大,这导致已经在< body> 开始之前刷新,等等。

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.

你真的需要调用代码之前的渲染响应阶段。在JSF 1.2中,您可以使用< f:view beforePhase>

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.

例如

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

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

然后你的Try-1和Try-3将工作(你可以留下那些 responseComplete() renderResponse()

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和Try-4差。您应该避免在您的备份bean中使用 javax.servlet。* 导入。 Try-5是笨拙的Try-6,Try-7和Try-8超出了我的范围。尝试9是可行的,但非常笨拙。

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.