У меня есть приложение JSF2, которое должно показывать страницу, в которой необходимо добавить число os элементов в списке. Пользователь хочет добавить эти элементы, установить некоторые их свойства и, наконец, сохранить их все вместе, в одной операции сохранения.Как сохранить список объектов в Java Server Faces 2
Объект домена, который должен быть обработан с помощью этой страницы выглядит следующим образом:
public class Item {
private long id;
private String name;
private Item previous;
public Item() { }
public Item(Item previousItem) {
this.previous = previousItem;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Item getPrevious() {
return previous;
}
}
ItemBean класс выглядит следующим образом:
@ManagedBean
public class ItemBean implements Serializable {
private static final long serialVersionUID = 1L;
private List<Item> items = new ArrayList<Item>();
public List<Item> getItems() {
if(items.size()==0) {
items.add(new Item()); // adding the first item
}
return items;
}
public void setItems(List<Item> items) {
this.items = items;
}
public void addItem(Item previousItem) {
Item newItem = new Item(previousItem);
items.add(newItem);
}
public void save() {
...
}
}
мнение является xhtml
файл что выглядит следующим образом:
<?xml version='1.0' encoding='UTF-8' ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html" xmlns:ui="http://java.sun.com/jsf/facelets">
<body>
<ui:composition template="/templates/layout.xhtml">
<ui:define name="content">
<h2>Items</h2>
<fieldset>
<legend>Items being added</legend>
<ui:repeat value="#{itemBean.items}" var="item">
<div>
<h:outputLabel value="Item" for="name" />
<h:inputHidden value="#{item.id}" />
<h:inputText id="name" value="#{item.name}" />
<h:commandLink action="#{itemBean.addItem(item)}">Add</h:commandLink>
</div>
</ui:repeat>
</fieldset>
<div class="options">
<h:commandButton action="#{itemBean.save}" value="Save"/>
<div class="clear border-bottom"></div>
</div>
</ui:define>
</ui:composition>
</body>
</html>
Обратите внимание, что для того, чтобы добавить новый элемент, необходимо отправить текущую информацию для соответствия бизнес-правилам.
Проблема в том, что я могу добавить второй элемент без проблем, но когда я нажимаю ссылку «Добавить» рядом со вторым элементом, страница перезаписывается одним отдельным элементом, как и в начале.
К сожалению, я не вижу, чего не хватает, чтобы заставить его работать, даже после чтения большого количества сообщений, страниц и некоторых разделов книг.
Update 1
меня спрашивали о том, какой объем используемой с этим компонентом. Это область по умолчанию (@RequestScoped
). Я пытался избежать использования @SessionScoped
ради масштабируемости, но в этом конкретном случае я не уверен, что у меня есть выбор. Любой, у кого больше опыта, может дать мне совет?
Спасибо за ваш ответ! Область действия - '@ RequestScoped', которая по умолчанию предназначена для управляемых компонентов. Я собирался спросить именно об этом.Я понимаю, что бит был уничтожен после того, как представление построено и возвращено в браузер, однако в других случаях, когда я поддерживал один экземпляр, JSF был достаточно умен, чтобы установить свойство одного экземпляра в состояние, которое было на этой странице, и я был ожидая того же самого для коллекции. Поскольку компоненты '@ SessionScoped' уменьшают масштабируемость приложения, я пытался избежать его. Что ты говоришь? Использует '@ SessionScoped' мой единственный выбор в этом сценарии? – AlexSC
@AlexSC Действительно, '@ SessionScoped' позволит вам сохранять ваши объекты на протяжении всего сеанса пользователя. Или вы можете сохранить свои объекты где-нибудь (sessionMap, файл, hibernate ...) – Thrax
'@ NoneScoped' - это область по умолчанию для управляемых компонентов @AlexSC – kolossus