【问题标题】:How to init parameters before @PostConstructor called in managed bean如何在托管 bean 中调用 @PostConstructor 之前初始化参数
【发布时间】:2013-04-08 13:40:57
【问题描述】:

我正在尝试在针对 MVC 调用 JSF @PostConstruvtor 之前初始化属性。

这是我的 Java 代码:

@ManagedBean
public abstract class FooController {
    protected <type> prop;

    public void setProp(<type> prop) {
        this.prop = prop;
    }

    public <type> getProp() {
        return this.prop;
    }
}

@ManagedBean
public class Foo1Controller extends FooController {
    private <otherType> myProp;

    @PostConstructor
    public void init {
        myProp = prop.getProp().getOtherTypeProp();
    }
}

[here I have more FooControllers Foo2Controller, Foo3Controller, Foo4Controller...]

@ManagedBean
public class MainController {
    // all props have getters and setters
    private FooController fooController;
    private int controllerType;
    private List<SelectItem> myTypes;
    private <type> prop;

    @PostConstructor
    public void init {
        // init myTypes here
        // init prop here
    }

    public static Object getBean(String s) {
        FacesContext context = FacesContext.getCurrentInstance();
        return context.getApplication().evaluateExpressionGet(context, "#{" + s + "}", Object.class);
    }

    public void controllerTypeChange (ValueChangeEvent event) {
        controllerType = Integer.valueOf(event.getNewValue().toString());

        if (controllerType == 1)
            fooController = (Foo1Controller) getBean("foo1Controller");
        else if (controllerType == 2)
            fooController = (Foo2Controller) getBean("foo2Controller");
        ....

        fooController.setProp(this.prop);
    }
}

这是 XHTML:

<o:SelectOneMenu id="fooType"
    value = #{"MainController.controllerType"}
    valueChangeListener = "#{MainController.controllerTypeChange}"
    styleClass = "dropdown">
    <o:ajax action = "#{MainController.controllerTypeChange}">
    <f:selectItems value = "MainController.myTypes">
</o:selectOneMenu>

<h:panelGroup id="component1" rendered="#{MainController.controllerType == 1}">
    <!-- some component here that uses foo1Controller as it's controller -->
</h:panelGroup>

<h:panelGroup id="component2" rendered="#{MainController.controllerType == 2}">
    <!-- some component here that uses foo2Controller as it's controller -->
</h:panelGroup>

问题是,当我在 MainController bean 中创建 foo1Controller 时,它已经使用了 foo1Controller @postConstructor 中的 prop 属性,但该属性为 NULL,因为它尚未初始化,我不知道该怎么做它在调用 post 构造函数之前。 我要做的事情背后的概念是 MainController 可以而且应该只有一个子组件,它们都有很多共同点,因此必须在这里进行继承。 当用户在下拉列表中选择某个值时,应显示相关组件,而 MainController 应具有对组件控制器的引用。

任何帮助将不胜感激。 谢谢!

【问题讨论】:

  • first:要获得有用的答案,您应该发布SSCCE,您的代码现在不是独立的,并且还存在语法错误。第二:解释你的问题和你想要实现什么,你只是描述你发布的代码,它不是独立的,不可编译的,所以你的问题很难理解。现在,我在您的代码中看到的是,您的 FooXController 从未初始化 prop 属性(甚至在 MainController 处也没有,而是尝试使用其中未初始化的值初始化 myProp
  • @Alonso Dominguez,我的真实课程太大,我无法发布它们,所以我尝试提取对描述问题很重要的内容,如果有不清楚的地方 - 请询问,我会解释.关于 FooXController 从不初始化道具的事情:道具值应该在 MainController 中初始化,并且 FooXController 从 PostConstructor 中的道具中获取一些其他属性,但问题是当我创建 FooXController bean时它是自动的调用 PostConstructor 需要使用该道具,但 MainController 仍然无法初始化它。
  • 抱歉太苛刻了,但如果你发布的小代码无法编译,很难知道问题出在哪里。我知道您正在尝试使用MainController 中的属性来初始化FooXController 中的prop 属性,我可以看到,但我没有看到您在哪里初始化MainController 的属性如果你正在初始化它(你的 init 方法是空的,它们甚至没有括号!)。请尝试发布 SSCCE,按照说明修剪您的代码,您甚至可以在请求之前找到问题的解决方案...
  • @Alonso Dominguez,我更新了代码,MainController 初始化了 PostConstructor 中的 prop 值(它实际上是从 DB - hibrenate 获取值)。
  • 如果&lt;type&gt;Managedbean?如果是这样,只需使用@ManagedProperty,这样prop 属性就会被注入FooController。如果没有,你不能使用@PostConstruct(没有'er'),因为它会在ManagedBean被烘焙之后被调用,这发生在你没有机会调用foo1Controller.setProp()方法的时候。

标签: model-view-controller jsf-2 primefaces managed-bean openfaces


【解决方案1】:

定义 servlet,它应该 GenericServlet 在您的应用程序中执行您想要的任何操作。并在 web.xml set load-on-startup 标签中定义它。 servlet 示例代码

public class ResourceInitializer extends GenericServlet {

@Override
    public void init(final ServletConfig config) throws ServletException {
        super.init(config);
// YOUR APPLICATION INIT CODE
}

@Override
    public void service(final ServletRequest req, final ServletResponse res)
            throws ServletException {
    }

    @Override
    public void destroy() {
        // tell the ResourceManager to cleanup and remove the resouces
        LibraOfficeService.getInstance().closeConnection();
        super.destroy();
    }
}

在 web.xml 中

 <servlet>
    <description>Initializes Resources</description>
    <servlet-name>ResourceInitializer</servlet-name>
    <servlet-class>packageNAME.ResourceInitializer</servlet-class>
    <load-on-startup>1</load-on-startup>
  </servlet>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-06
    • 2014-09-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-12
    • 1970-01-01
    相关资源
    最近更新 更多