1

嗨,我正在玩 jsf 2.1

我有以下处理程序

@Controller("testHandler")
@Scope("request")
public class TestHandler {

    public class EntityObject {

        public EntityObject(String value) {
            this.value = value;
        }

        private String value = "";

        public String getValue() {
            return value;
        }

        public void setValue(String value) {
            log.info(this + " Set value from " + this.value + " to " + value);
            this.value = value;
        }
    }

    private Logger log = Logger.getLogger(getClass());

    private List<EntityObject> objects = new ArrayList<TestHandler.EntityObject>();

    @PostConstruct
    public void init() {
        log.info("INIT");
        // addItem("O0");
        addItem("O1");
        addItem("O2");
        addItem("O3");
    }

    private void addItem(String name) {
        EntityObject e = new EntityObject(name);
        log.info("add " + e + " with value " + name);
        objects.add(e);
    }

    public List<EntityObject> getObjects() {
        return objects;
    }

    public void setObjects(List<EntityObject> objects) {
        this.objects = objects;
    }

}

而这个jsf

    <h:form>
        <h:dataTable value="#{testHandler.objects}" var="object">

            <h:column>
                <h:inputText value="#{object.value}" />
            </h:column>

        </h:dataTable>

        <h:commandButton value="submit" />
    </h:form>

我在调试模式下运行tomcat,所以我可以热替换代码。

现在我正在打开页面

init | INIT
addItem | add TestHandler$EntityObject@41c3cce3 with value O1
addItem | add TestHandler$EntityObject@1dc06cd0 with value O2
addItem | add TestHandler$EntityObject@4427daf2 with value O3
  • 我看到有 3 个输入字段的表格
  • 我在每个值的末尾添加“更改”
  • 我取消注释“addItem(“O0”);” 在初始化方法中
  • 我点击提交按钮

->

init | INIT
addItem | add TestHandler$EntityObject@5d653eaa with value O0
addItem | add TestHandler$EntityObject@21f53acd with value O1
addItem | add TestHandler$EntityObject@6ae77a25 with value O2
addItem | add TestHandler$EntityObject@30449f8 with value O3
setValue | TestHandler$EntityObject@5d653eaa Set value from O0 to O1change
setValue | TestHandler$EntityObject@21f53acd Set value from O1 to O2change
setValue | TestHandler$EntityObject@6ae77a25 Set value from O2 to O3change

在日志中,似乎没有将值分配给之前引用的对象,jsf 似乎只是记忆了列表的索引并更新了错误的对象。

更新对象的最佳范围是什么?如何归档最新列表以及从表到对象的可靠映射?

添加equals和hashcode函数没有帮助

4

2 回答 2

0

事实上,JSF 并没有更新错误的对象。引用著名文章JSF 2.0 中的通信

@RequestScoped:只要 HTTP 请求-响应存在,此范围内的 bean 就会存在。它在 HTTP 请求时创建,并在与 HTTP 请求关联的 HTTP 响应完成时被销毁(这也适用于 ajax 请求!)。

因此,当您点击“点击”按钮时,您的 bean 会被销毁并创建;在初始化期间,它会初始化您的 EntityObject 数组,因此您无法保存状态。

您可以阅读不同类型范围的链接,然后选择最适合您兴趣的类型。如果您没有具体案例,ViewScoped可能会对您有所帮助。

于 2013-03-06T16:32:14.830 回答
0

Looks like you are mis-using the Request scope. It is not appropriate for updatable data. Beans in request scope are created for every request (button push or even AJAX call).

When you hit submit button, JSF will create new request and your request scope bean will be destoryed. But because you are staying on the same page, the JSF DataTable bean is not destoryed and it will go through all components and update the values.

Note that at this point JSF Table bean has three InputText components, it will update them: ie. only the first three items in list. JSF doesnt keep the full data in components, (waste of memory), just references.. So here's funny thing: if you create two items in second Init() JSF will give you an error.

Here is an excellent explanation of scopes with guidelines: http://balusc.blogspot.ca/2011/09/communication-in-jsf-20.html#ManagedBeanScopes

see also: How to choose the right bean scope?

于 2013-03-06T17:03:30.197 回答