NullPointerException绑定不起作用JSF托管bean

4
我创建了一个简单的HtmlInputText。
  <h:inputText binding="#{IndexBean.objUIInput}" />

然后在我的托管bean中,代码如下:

   private   UIInput objUIInput;

    public UIInput getObjUIInput() {
        objUIInput.setValue("laala");
        return objUIInput;
    }

    public void setObjUIInput(UIInput objUIInput) {
        System.out.println("Set!!");
        this.objUIInput = objUIInput;
    }

但是我总是得到NullpointerException错误。我需要在JSF页面上做额外的事情吗?就像我们在jsp:usebean setproperty那样?请帮助我。


1
你是如何声明你的托管 Bean 的?你什么时候遇到了异常? - Bozho
我完全没有触碰托管bean。它是由Netbeans 6.8 IDE生成的,带有@ManagedBean注释。此外,我想说的一件事是,如果我将其绑定到其他属性,如value =“{IndexBean.sayHello}”,那么它就可以完美地运行。但是,一旦使用binding属性,它就会失败。而且,如果我使用new关键字初始化HtmlInputText实例,则可以正常工作。问题可能是什么?当我刷新页面时,会出现异常。我的意思是setter根本没有被触发。我在Glassfish控制台中看不到任何内容,因为我已经打印了System.out.println(“Set!”)。请帮忙! - TCM
2个回答

5

如果您想在显示组件之前更改其默认状态/行为,那么您需要自己进行实例化。即在声明期间:

private UIInput objUIInput = new HtmlInputText();

或者在建设期间:

public Bean() {
    this.objUIInput = new HtmlInputText();
}

或者,正如Bozho建议的那样,使用@PostConstruct
@PostConstruct
public void init() {
    this.objUIInput = new HtmlInputText();
}

(这将发生在bean构建和初始化/设置所有托管属性之后)。

确实,最好不要在getter/setter中执行任何业务逻辑。它们用于访问bean属性,并且在bean的生命周期内可能会被调用多次。

根据评论,您还可以将UIInput#setValue()调用移动到setter方法中。 JSF将在预创建组件后直接调用它一次。

public void setObjUIInput(UIInput objUIInput) {
    this.objUIInput = objUIInput;
    this.objUIInput.setValue("laala");
}

我理解BalusC,但我正在使用Primefaces组件,它不起作用。如果我创建对象的新实例,它就不起作用。相信我!让我这样说:我的要求只是JSF应该传递引用到我的托管bean,我只能在那个同样的引用上工作,我不想创建新的实例,否则它就不起作用。我知道你不会相信,但事实就是这样。 @PostConstruct是一个很好的方法,但它也不起作用,因为它在依赖注入(如果有)之后和setter之前被触发。我希望在setter被触发后再触发某些东西。 - TCM
1
那只是一个例子。用实际绑定的Primefaces组件替换HtmlInputText。或者,您可以在getter方法中添加一个nullcheck,或者(更好地)将setValue()调用移动到setter方法中。JSF在预创建实际组件后直接调用setter。这里保证非空。 - BalusC
好的!太棒了!如果它只被调用一次,那就没问题了!谢谢朋友!现在你终于理解我了。 :) 你们真棒。我们在这个论坛上的响应时间简直惊人。感觉就像我们在聊天一样。Stackoverflow 真是太棒了!! - TCM
2
你为什么大喊大叫地使用“ya”,“dude”和感叹号?请停止这种行为并冷静下来。人们可能会认为你不够严肃(幼稚)而离开。无论如何,另一种方法就是在视图中定义value="#{bean.property}",并在bean的初始化或构造期间预设 this.property - BalusC
好的,抱歉我会删除所有感叹号和其他幼稚的词语。事实上,在最终解决此问题之前,我一直在尝试解决它。再次抱歉。 - TCM

1
当您绑定组件时,getter和setter应该很简单-只有get/set,里面不应包含逻辑。
也许JSF生命周期正在调用getter以检查是否需要实例化组件,并且getter最初会抛出NPE。
从getter中删除所有逻辑,或者至少添加一个null检查。
实际上,我建议根本不使用绑定。
如果要将初始值设置为组件,则使用带有@PostConstruct注释的方法并在那里分配值,然后使用value属性。

不起作用啊兄弟。我已经尝试了所有可能的方法:1)使用@PostConstruct,然后直接设置value属性不起作用,因为setter在@PostConstruct之后被触发。我通常只想在JSF将组件对象的引用传递给我的托管bean时才执行某些操作。2)如果在getter上放置一个非空检查,然后设置它的值,这次就不会触发NPE,但我看不到组件中的值。3)如果在JSF传递引用到托管bean之后在setter中设置,那么它就可以正常工作。但这有点像打补丁。请帮帮我吧,朋友。 - TCM

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接