子进程的JSF自定义组件requestmap值为null

时间:2015-10-08 18:48:24

标签: jsf jsf-2

我创建了一个组件,用于访问基于数字转换为其他类型的通用对象。我在请求映射中使用“var”属性,以允许组件中的子级访问该对象。当尝试访问子组件中由“var”命名的对象时,我得到以下异常: javax.el.PropertyNotFoundException:目标无法访问,标识符'objectName'已解析为null。

这是我的组件代码和标记:

@FacesComponent(value = "components.AgendaItemTextAccessor", createTag = true)
public class AgendaItemTextAccessor  extends UIComponentBase{
public String getVar(){
    return (String) getStateHelper().eval("var");
}
public void setVar(String var){
    getStateHelper().put("var", var);
}
public AgendaItemText getValue(){
    return (AgendaItemText) getStateHelper().eval("value");
}
public void setValue(AgendaItemObject text){
    getStateHelper().put("value", text);
}

@Override
public boolean getRendersChildren() {
    return true;
}

@Override
public void encodeChildren(FacesContext context) throws IOException{
    if ((context == null)){
        throw new NullPointerException();
    }

    AgendaItemText text = (AgendaItemText)getValue();
    String varname = getVar();
    Map<String, Object> requestMap = context.getExternalContext().getRequestMap();

    Object varStore = requestMap.get(varname); // in case this Object already exists in the requestMap,
                                        // emulate "scoped behavior" by storing the value and
                                        // restoring it after all rendering is done.

    if(text != null){
        requestMap.put(varname, text);
        for(UIComponent child: getChildren()){
            child.encodeAll(context);
        }         
        // restore the original value
        if(varStore != null){
            requestMap.put(varname, varStore);
        }else{
            requestMap.remove(varname);
        }
    }
}

@Override
public String getFamily() {
    return "components.AgendaItemTextAccessor";
}

标记

<xx:agendaItemTextAccessor value="#{itemValue}" var="itemVar">
    <p:inputText value="#{itemVar.text}">
        <p:ajax event="blur" listener="#{Controller.printMe(itemVar)}" />
    </p:inputText>
</xx:agendaItemTextAccessor>

1 个答案:

答案 0 :(得分:1)

  

我们被指示创建一个组件,该组件接受抽象对象并基于定义其类型的字段将其强制转换

你在实现功能要求方面走错了方向。 out增加了不必要的复杂性。只需直接使用var即可。在EL中,无论如何都是#{itemValue}(反射,你知道),因此在将它放回EL之前绝对不需要向上,向下,向左或向右倾斜。

Object

关于具体问题,您遇到了这个问题,因为您只在<p:inputText value="#{itemValue.text}"> <p:ajax event="blur" listener="#{controller.printMe(itemValue)}" /> </p:inputText> 期间而不是在encodeChildren()processDecodes()processValidators()processUpdates()期间设置了它。换句话说,它仅在呈现响应阶段期间可用,而不是在可能相关的所有其他阶段期间可用。遗憾的是,你没有在任何地方显示完整的堆栈跟踪,但它应该指出哪个阶段是有罪的(我的有根据的猜测说broadcast())。通常,processValidators()仅在转发器或仅输出组件中实现。查看source code of var如何正确操作(并查看source code<o:tree>如何以干的方式执行此操作。)