Как отобразить список элементов из Bean на веб-страницу JSF?
Я новичок в JSF и в процессе обучения создаю приложение онлайн-магазина книг.
У меня есть 1 класс и 1 bean: Book.java
и BookCatelogBean.java
. Класс Book имеет 3 свойства: id
, title
и author
с ним соответствующие геттеры и сеттеры. BookCatelogBean
содержит ArrayList<Book>
, где я заполняю его Books
(в будущем я подключу его к базе данных).
У меня две страницы: index.xhtml
и book.xhtml
. Я хочу отобразить список названий книг на index.xhtml
, каждый из которых отформатирован как ссылка REST и их идентификатор на book.xhtml
, например: <h:link outcome="book?id=#{bookCatelogBean.id}" value="#{bookCatelogBean.title}" />
Я знаю, как использовать BookCatelogBean
для отображения 1 book
, но я хочу отобразить их все? У меня есть идея вызвать метод из BookCatelogBean
, называемый getAllBooks()
, который возвращает каждый из названий книг, но как я могу вернуть каждый из них в index.xhtml как ссылку JavaserverFace вместо строки?
Спасибо
Вот мой код:
Book.java
package bookshop;
import java.io.Serializable;
public class Book implements Serializable {
private int id;
private String title;
private String author;
public Book(int id, String title, String author){
this.title = title;
this.id = id;
this.author = author;
}
public String getAuthor() {
return author;
}
public void setAuthor(String author) {
this.author = author;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
}
BookCatelogBean.java
package bookshop;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Arrays;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.SessionScoped;
@ManagedBean
@SessionScoped
public class BookCatelogBean implements Serializable {
private int currentItem = 0;
private ArrayList<Book> books = new ArrayList<Book>(Arrays.asList(
new Book(1, "Theory of Money and Credit", "Ludwig von Mises"),
new Book(2, "Man, Economy and State", "Murry Rothbard"),
new Book(3, "Real Time Relationships", "Stefan Molyneux")));
public String getTitle(){
return books.get(currentItem).getTitle();
}
public int getId(){
return books.get(currentItem).getId();
}
public String getAuthor(){
return books.get(currentItem).getAuthor();
}
}
index.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:h="http://java.sun.com/jsf/html">
<h:head>
<title>BookShop</title>
</h:head>
<h:body>
<h:link outcome="book?id=#{bookCatelogBean.id}" value="#{bookCatelogBean.title}" />
</h:body>
</html>
Ответы
Ответ 1
JSF2 предлагает два итерационных компонента из коробки: <ui:repeat>
и <h:dataTable>
. Первый ничего не делает для ответа (так что у вас есть 100% контроль над окончательным выходом HTML), в то время как последний отображает HTML <table>
в ответ и требует <h:column>
для представления столбца <td>
s. Оба компонента могут принимать среди других значение List<E>
как значение.
Итак, вы можете просто использовать свой управляемый bean следующим образом:
@ManagedBean
@RequestScoped
public class BookCatalog implements Serializable {
private List<Book> books;
@PostConstruct
public void init() {
books = new ArrayList<Book>();
books.add(new Book(1, "Theory of Money and Credit", "Ludwig von Mises"));
books.add(new Book(2, "Man, Economy and State", "Murry Rothbard"));
books.add(new Book(3, "Real Time Relationships", "Stefan Molyneux"));
}
public List<Book> getBooks() {
return books;
}
}
И вы можете использовать <ui:repeat>
для генерации, например, <ul><li>
:
<ul>
<ui:repeat value="#{bookCatalog.books}" var="book">
<li>
<h:link value="#{book.title}" outcome="book">
<f:param name="id" value="#{book.id}" />
</h:link>
</li>
</ui:repeat>
</ul>
(обратите внимание, что атрибут var
в основном предоставляет текущий итерированный элемент точно заданным именем в области EL в компоненте)
А вот как использовать <h:dataTable>
вместо этого:
<h:dataTable value="#{bookCatalog.books}" var="book">
<h:column>
<h:link value="#{book.title}" outcome="book">
<f:param name="id" value="#{book.id}" />
</h:link>
</h:column>
</h:dataTable>
Что касается JSTL <c:forEach>
, это также вполне возможно, но вы должны иметь в виду, что теги JSTL имеют другой жизненный цикл, чем компоненты JSF. Короче говоря: JSTL в JSF2 Facelets... имеет смысл?
См. также:
Ответ 2
Также вы можете использовать библиотеку
Первичные данные datatable