使用JSF自动设置托管bean变量的值

时间:2017-01-25 13:33:22

标签: jsf primefaces jsf-2 managed-bean

我想将值传递给引擎盖下的托管bean。所以我有这个托管bean:

@ManagedBean(name = "mbWorkOrderController")
@SessionScoped
public class WorkOrderController {

    // more attributes...

    private WorkOrder workOrderCurrent;

    // more code here...

    public WorkOrder getWorkOrderCurrent() {
        return workOrderCurrent;
    }

    public void setWorkOrderCurrent(WorkOrder workOrderCurrent) {
        this.workOrderCurrent = workOrderCurrent;
    }
}

它包含自定义类型workOrderCurrent的参数WorkOrder。班级WorkOrder的属性applicant类型为String

目前我在placeholder内使用inputtext向用户显示他需要在inputText内输入的内容。

<p:inputText id="applicant"
    value="#{mbWorkOrderController.workOrderCurrent.applicant}"
    required="true" maxlength="6"
    placeholder="#{mbUserController.userLoggedIn.username}" />

我想要做的是自动将mbUserController.userLoggedIn.username的值传递给mbWorkOrderController.workOrderCurrent.applicant,并从我的表单中完全删除inputText applicant

我尝试使用c:set

<c:set value="#{mbUserController.userLoggedIn.username}" target="#{mbWorkOrderController}" property="workOrderCurrent.applicant" />

但不幸的是,我收到了javax.servlet.ServletException的消息:

“WorkOrderController”类没有属性“workOrderCurrent.applicant”。

有人有建议吗?

2 个答案:

答案 0 :(得分:3)

  

“WorkOrderController”类没有属性“workOrderCurrent.applicant”。

您的<c:set>语法不正确。

<c:set value="#{mbUserController.userLoggedIn.username}"
       target="#{mbWorkOrderController}" 
       property="workOrderCurrent.applicant" />

你似乎在考虑那部分..

value="#{mbWorkOrderController.workOrderCurrent.applicant}"

..工作如下:

WorkOrderCurrent workOrderCurrent = mbWorkOrderController.getWorkOrderCurrent();
workOrderCurrent.setApplicant(applicant);
mbWorkOrderController.setWorkOrderCurrent(workOrderCurrent);

事实并非如此。它的工作原理如下:

mbWorkOrderController.getWorkOrderCurrent().setApplicant(applicant);

因此,正确的<c:set>语法如下:

<c:set value="#{mbUserController.userLoggedIn.username}"
       target="#{mbWorkOrderController.workOrderCurrent}" 
       property="applicant" />

尽管如此,所有这些都不是the concrete problem you actually tried to solve的正确解决方案。您应该在模型本身中执行模型预填充。这可以通过使用@ManagedProperty引用另一个bean属性并使用@PostConstruct基于它来执行初始化来实现。

@ManagedBean(name = "mbWorkOrderController")
@SessionScoped
public class WorkOrderController {

    @ManagedProperty("#{mbUserController.userLoggedIn}")
    private User userLoggedIn;

    @PostConstruct
    public void init() {
        workOrderCurrent.setApplicant(userLoggedIn.getUsername());
    }

    // ...
}

答案 1 :(得分:0)

也许您可以更多地解释上下文,但这是另一种解决方案。如果您从其他页面导航,则可以在URL中传递一些工作标识符WorkOrder,如http://host:port/context/page.xhtml?workOrderId=1

然后,您可以在托管bean中设置标识符,如下所示:

<h:html>
    <f:viewParam name="workOrderId" value="#{mbWorkOrderController.id}"/>
</h:html>

您必须向bean添加新属性:

public class WorkOrderController {
    private long id;
    public long getId() { return id; }
    public void setId(long id) { this.id = id; }

    // ...
}

然后,在JSF设置该属性之后,您可以在生命周期事件中找到工作订单:

<h:html>
    <f:viewParam name="workOrderId" value="#{mbWorkOrderController.id}"/>
    <f:event type="preRenderView" listener="#{mbWorkOrderController.findWorkOrder()}"/>
</h:html>

public class WorkOrderController {
    private long id;
    public long getId() { return id; }
    public void setId(long id) { this.id = id; }

    public void findWorkOrder() {
        this.workOrderCurrent = null /* some way of finding the work order */
    }

    // ...
}

此策略的优势在于您可以使用可收藏的网址。