本文介绍了JSF 2.0:何时调用encodeAll以及何时何时调用encodeBegin?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑自定义UIComponent(仅用于测试目的):

Consider a custom UIComponent (for test purposes only):

public class UITest extends UIComponentBase {

    @Override
    public void encodeBegin(FacesContext context) throws IOException {
        System.out.println("encodeBegin");
    }

    @Override
    public void encodeAll(FacesContext context) throws IOException {
        System.out.println("encodeAll");
    }

}

当我将其添加到复合组件内部的页面时,会调用encodeBegin()方法.但是,将其添加到复合组件之外的页面时,将改为调用encodeAll()方法.

When I add it to page inside a composite component, the encodeBegin() method gets called. However, when add it to page outside a composite component, the encodeAll() method gets called instead.

将其添加到其他UIComponent中没有什么区别,只有复合组件包装程序似乎可以改变行为.

Adding it inside other UIComponents makes no difference, only composite component wrapper seems to change the behavior.

找不到信息为什么会这样?规范的链接?

Couldn't find info why it is so? A link to the spec?

推荐答案

在这种情况下,规范确实很混乱,指出:这些方法是在请求处理生命周期的渲染响应"阶段中调用的.encodeAll()将导致此组件及其从isRendered()返回true的所有子项和构面都将被呈现,无论getRendersChildren()返回值的值. encodeBegin(),encodeChildren()和encodeEnd()负责为此组件的开头创建响应数据,组件的子项(仅当此组件的rendersChildren属性为true时才调用),并且以该组件."

The spec is really messy in this case, stating that:"These methods are called during the Render Response phase of the request processing lifecycle. encodeAll() willcause this component and all its children and facets that return true from isRendered() to be rendered, regardlessof the value of the getRendersChildren() return value. encodeBegin(), encodeChildren(), andencodeEnd()have the responsibility of creating the response data for the beginning of this component, thiscomponent’s children (only called if the rendersChildren property of this component is true), and the ending ofthis component, respectively."

但是,这似乎是新旧功能的混合,其中新功能(encodeAll)在某些方面似乎不完整:

However, this seems to be a mixture of new and old features, where the new functionality (encodeAll) seems to be incomplete in some ways:

我尝试了以下操作:

A)直接在页面中调用组件(无包装)

A) Calling the component directly in the page (no wrapper)

  1. 扩展UIComponentBase(或其他UIComponent类,如UIInput,UIOutput等),将其声明为标记,并在UI中使用它.在这种情况下,如果存在(被覆盖),则将被称为encodeAll方法,否则,将被称为encodeBegin和encodeEnd方法!

  1. extend UIComponentBase (or other UIComponent class such as UIInput, UIOutput.. etc), declare it as a tag, and use it in the UI.In this case the encodeAll method is called IF it is present (overridden), if not the encodeBegin and encodeEnd methods will be called!!

要注意的另一件事是,您可以为组件创建自定义Renderer,因此可以将渲染逻辑与行为分开. (通过创建另一个扩展Renderer的类,并使用@FacesRenderer对其进行注释)这就是它变得有趣的地方.渲染器仅定义encodeBegin,encodeChildren和encodeEnd(未提及encodeAll).现在,逻辑似乎大致如下:如果(存在encodeAll)调用encodeAll(并且渲染器将被忽略!)否则,如果(在扩展UIComponent的类中存在encodeBegin,Children或end中的任何一个)调用在该组件中找到的方法否则if(encodeBegin,children或end在扩展Renderer的类中存在)调用找到的相应方法.

Another thing to note is that you can create a custom Renderer for the component, so you can separate rendering logic from behaviour. (by creating another class that extends Renderer, and annotating it with @FacesRenderer)This is where it gets interesting; Renderer defines only encodeBegin, encodeChildren and encodeEnd (with no mention of encodeAll).Now the logic seems to go roughly like this:if (encodeAll is present)encodeAll is called (and the renderer is ignored!)else if(any of encodeBegin,Children,or end exist in the class that extends UIComponent)call the method that was found in that componentelse if(encodeBegin, children or end exist in the class that extends Renderer)call the corresponding method that was found.

因此,这意味着在扩展UIComponent的类中实现encodeAll(或encodeBegin ..等)会导致渲染器被忽略!

So this means that implementing encodeAll (or encodeBegin.. etc ) in the class extending UIComponent causes the renderer to be ignored!

B)包装组件(抄送:实现等)

B) Wrapping the component (cc:implementation.. etc)

在这种情况下,发生了与上述相同的事情,除了无论如何我都没有调用encodeAll.

In this case the same thing happened as above, except that encodeAll was not called in any case, no matter what I did.

结论:看来encodeAll是实现呈现代码的某种新功能(或捷径),并且在这种情况下cc:implementation似乎有一个错误(它不会寻找encodeAll).

Conclusion:It seems that encodeAll is some kind of new functionality (or shortcut) to implement the rendering code, and it seems that cc:implementation has a bug in this case (it doesn't look for encodeAll).

我希望这对您至少有价值,不幸的是,我无法提供更详尽的答案. :(似乎其他人对此一无所知.

I hope this is at least of some value to you, unfortunately I cannot provide a more thorough answer. :(It also seems that nobody else knows about this.

这篇关于JSF 2.0:何时调用encodeAll以及何时何时调用encodeBegin?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

05-22 06:03