从 Core JSF 迁移到 Seam 时移植托管 Bean 的功能

发布于 2024-12-10 18:45:09 字数 3889 浏览 0 评论 0原文

我曾经在 jsf 托管 bean(甚至托管 bean 的构造函数)的 @PostConstruct 方法中实例化实体对象时就使用预定义值来初始化该实体对象的某些属性。当将项目移植到 Seam 且托管 bean 消失时,我无法再保留此功能(还想知道在没有托管 bean 的 JSF 2.2 中会怎样)。

实体类:

@Entity
@Name("task") // this line in Seam version
public class Task implements Serializable {

    private Integer id;
    private String subject;
    private Date creationDate;
    private Date completionDate;
    private Category category;
    private User user;

    public Task() {
    }

    public Task(Date creationDate) {
        this.creationDate = creationDate;
        this.user = user;
    }

    // getters & setters, etc.
}

JSF 托管 Bean

public class TaskBean extends BaseBean {

    // Super class provides the logged in user object and a default category object

    private Task task = new Task(java.util.Calendar.getInstance().getTime(), this.user);

    @PostConstruct
    public void initTaskBean() {
        if (certainConditionMet) 
            task.setCategory(defaultCategory);
    }

    // Other managed bean business...
}

JSF 页面

<h:form>
<h:panelGrid columns="2">
    Date: <h:outputText value="#{taskBean.task.creationDate}">
            <f:convertDateTime pattern="dd/MM/yyyy" />
           </h:outputText>
    User:  <h:outputText value="#{taskBean.task.user.name}" />
    Subject: <h:inputText value="#{taskBean.task.subject}" id="subjectField" />
    Category: <h:selectOneMenu value="#{taskBean.task.category}" id="catMenu">
                <f:selectItems value="#{taskBean.categories}" />
              </h:selectOneMenu>
    // remaining stuff
</h:panelGrid>
</h:form>

Seam 版本中的无状态会话 Bean 也承担了 jsf 托管的责任bean

@Name("taskAction")
@Stateless
public class TaskAction implements TaskActionLocal {

    @PersistenceContext
    private EntityManager em;

    @In private FacesMessages facesMessages;
    @In User user;
    @In Category defaultCategory
    @Logger private Log log;

    @In
    // private Task task = new Task(java.util.Calendar.getInstance().getTime(), user)
    // the above didn't work so 
    private Task task; 

    @PostConstruct
    public void baslarken() {
        System.out.println("TaskAction PostConstructed");
        task = new task(java.util.Calendar.getInstance().getTime(), user);
        if (certainConditionMet) 
                task.setCategory(defaultCategory);

        // the above won't work either. Date and User always blank on the ui form
    }

    // other business methods, etc
}

Seam 版本的表单:

<h:form id="todo" styleClass="edit">
    <rich:panel>
        <f:facet name="header">Task To Do</f:facet>

        <s:decorate id="dateField" template="layout/edit.xhtml">
            <ui:define name="label">Date:</ui:define>
            <h:outputText value="#{task.creationDate}"/>
        </s:decorate>

        <s:decorate id="userField" template="layout/edit.xhtml">
            <ui:define name="label">User:</ui:define>
            <h:outputText value="#{task.user.name}"/>
        </s:decorate>

        <s:decorate id="subjectField" template="layout/edit.xhtml">
            <ui:define name="label">Başlık</ui:define>
            <h:inputText id="subject" required="true" value="#{task.subject}" >
            <a4j:support event="onblur" reRender="subjectField" bypassupdates="true" ajaxSingle="true" />
            </h:inputText>
        </s:decorate>

        <!-- other components, etc -->
    </rich:panel>
</h:form>

我需要有关如何使任务对象在实例化时预先填充日期和登录用户数据(最好是默认类别)的建议。

I used to initialize certain properties of an entity object with pre-defined values as early as its instantiation in a @PostConstruct method of a jsf managed bean (or even the managed bean's constructor). I can no longer preserve this functionality when porting the project to Seam with the managed bean gone (wondering also how it would be in JSF 2.2 without managed beans).

The entity class:

@Entity
@Name("task") // this line in Seam version
public class Task implements Serializable {

    private Integer id;
    private String subject;
    private Date creationDate;
    private Date completionDate;
    private Category category;
    private User user;

    public Task() {
    }

    public Task(Date creationDate) {
        this.creationDate = creationDate;
        this.user = user;
    }

    // getters & setters, etc.
}

The JSF Managed Bean

public class TaskBean extends BaseBean {

    // Super class provides the logged in user object and a default category object

    private Task task = new Task(java.util.Calendar.getInstance().getTime(), this.user);

    @PostConstruct
    public void initTaskBean() {
        if (certainConditionMet) 
            task.setCategory(defaultCategory);
    }

    // Other managed bean business...
}

The JSF page

<h:form>
<h:panelGrid columns="2">
    Date: <h:outputText value="#{taskBean.task.creationDate}">
            <f:convertDateTime pattern="dd/MM/yyyy" />
           </h:outputText>
    User:  <h:outputText value="#{taskBean.task.user.name}" />
    Subject: <h:inputText value="#{taskBean.task.subject}" id="subjectField" />
    Category: <h:selectOneMenu value="#{taskBean.task.category}" id="catMenu">
                <f:selectItems value="#{taskBean.categories}" />
              </h:selectOneMenu>
    // remaining stuff
</h:panelGrid>
</h:form>

The Stateless Session Bean in Seam version also assuming the responsibility of the jsf managed bean

@Name("taskAction")
@Stateless
public class TaskAction implements TaskActionLocal {

    @PersistenceContext
    private EntityManager em;

    @In private FacesMessages facesMessages;
    @In User user;
    @In Category defaultCategory
    @Logger private Log log;

    @In
    // private Task task = new Task(java.util.Calendar.getInstance().getTime(), user)
    // the above didn't work so 
    private Task task; 

    @PostConstruct
    public void baslarken() {
        System.out.println("TaskAction PostConstructed");
        task = new task(java.util.Calendar.getInstance().getTime(), user);
        if (certainConditionMet) 
                task.setCategory(defaultCategory);

        // the above won't work either. Date and User always blank on the ui form
    }

    // other business methods, etc
}

Seam version of the form:

<h:form id="todo" styleClass="edit">
    <rich:panel>
        <f:facet name="header">Task To Do</f:facet>

        <s:decorate id="dateField" template="layout/edit.xhtml">
            <ui:define name="label">Date:</ui:define>
            <h:outputText value="#{task.creationDate}"/>
        </s:decorate>

        <s:decorate id="userField" template="layout/edit.xhtml">
            <ui:define name="label">User:</ui:define>
            <h:outputText value="#{task.user.name}"/>
        </s:decorate>

        <s:decorate id="subjectField" template="layout/edit.xhtml">
            <ui:define name="label">Başlık</ui:define>
            <h:inputText id="subject" required="true" value="#{task.subject}" >
            <a4j:support event="onblur" reRender="subjectField" bypassupdates="true" ajaxSingle="true" />
            </h:inputText>
        </s:decorate>

        <!-- other components, etc -->
    </rich:panel>
</h:form>

I need advice on how to make the task object to hold the date and logged in user data (and preferably a default category) pre-populated when instantiated.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

年华零落成诗 2024-12-17 18:45:10

首先,我很抱歉,但我找不到这个答案的评论链接? (所以版主可以随意移动这篇文章;))

将entityhome类扩展为会话bean应该是可能的。但我不确定这样做是否正确。我更有可能创建一个新的会话 bean 来更准确地满足我的目的。

用于工厂调用。您将从 jsf 页面中以与任何其他名称相同的方式调用它。即值=“#{createNewTask.id}”。或者你可以将它注入到另一个类中。看看接缝文档。写得确实很好。

First im sorry but i cannot find a comment link on this answer?? ( so moderators feel free to move this post;) )

Extending the entityhome class as a session bean should be possible yes. But if its the right thing to do i'm not sure. I would more likely create a new session bean that serves my purpose more exact.

For the factory invocation. You will call this the same way from a jsf page as any other name. I.e. value="#{createNewTask.id}". Or you can inject it into another class. Take a look at the seam doc. Its really well written.

哑剧 2024-12-17 18:45:10

您可以通过多种方式来初始化实体。您可以为实体扩展 EntityHome 类。它是编辑器处理实体的默认实现。如果您使用 seam-gen 创建应用程序,也会使用它。

这看起来像这样:

@Name("queryHome")
@Scope(ScopeType.CONVERSATION)
public class QueryHome extends EntityHome<Query> {
    /*
     * (non-Javadoc)
     * @see org.jboss.seam.framework.Home#createInstance()
     */
    @Override
    public Query createInstance() {
        Query query = super.createInstance();
        query.setUser(loggedUser);
        query.setCreationDate(new Date());
        query.setLastExecutionDate(new Date());
        return query;
    }
}

您将调用 queryHome.getInstance()。
如果设置了entityHome中的id属性,它将尝试从数据库中加载具有该id的实体,如果没有id,它将调用createInstance()。
这就是我通常使用它的方式。

您还可以在Seam 托管bean 中创建工厂注释方法。在那里你可以做任何你喜欢做的事。

@Name("CreationFactory")
@Scope(ScopeType.STATELESS)
pulic class CreationFactory {

    @Factory("createNewTask")
    public Task createTask() {
        Task task = new Task();
        task.sometext = "sometext";
        return task;
    }
}

我通常不会直接访问或创建 bean,但我使用像entityhome 这样的管理器组件来执行此操作。您可以使用工厂来简化访问,但这在 Seam 文档中进行了解释。

马丁

You have several possibilities to initialize an entity. There is the EntityHome class that you can extend for an entity. It's the default implementation of handling entities for an editor. It is also used if you use seam-gen to create your application.

This would look something like this:

@Name("queryHome")
@Scope(ScopeType.CONVERSATION)
public class QueryHome extends EntityHome<Query> {
    /*
     * (non-Javadoc)
     * @see org.jboss.seam.framework.Home#createInstance()
     */
    @Override
    public Query createInstance() {
        Query query = super.createInstance();
        query.setUser(loggedUser);
        query.setCreationDate(new Date());
        query.setLastExecutionDate(new Date());
        return query;
    }
}

And you will be calling queryHome.getInstance().
If the id property in entityHome is set it will try to load the entity with this id from the database, and if there is no id it will call createInstance().
This is how i use it normally.

You can also create a factory annotated method in a seam managed bean. There you can do whatever you like.

@Name("CreationFactory")
@Scope(ScopeType.STATELESS)
pulic class CreationFactory {

    @Factory("createNewTask")
    public Task createTask() {
        Task task = new Task();
        task.sometext = "sometext";
        return task;
    }
}

I normally do not access or create a bean directly but i use a manager component like the entityhome to do it. You can simplify the access with a factory, but this is explained in the Seam documentation.

Martin

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文