#jsf-2 #jpa-2.0 #glassfish-3
#jsf-2 #jpa-2.0 #glassfish-3
Вопрос:
Если у меня есть h:dataTable
в books.xhtml, предоставляющий список записей, и я хочу просмотреть конкретную запись, затем добавить или отредактировать эту запись, в настоящее время у меня есть это:
<h:dataTable #{BookBean.books}" var="books">
<h:link outcome="bookview" value="#{books[1]}">
<f:param name="id" value="#{books[2]}" />
</h:link>
</h:dataTable>
Я обнаружил, что мне нужно включить, <f:param>
чтобы показать CSS-статус нажатой ссылки; в противном случае, если у меня его нет <f:param>
, каждый раз, когда я нажимаю на ссылку, отображаемую тегами h: link в приведенных выше кодах, все ссылки изменяются на CSS-статус нажатой.
Кроме того, я где-то читал о getrowdata()
, но мне не удалось заставить его работать. Является ли это лучшей альтернативой использованию <f:param>
?
Я попробовал getrowdata()
метод в моем классе BookBean следующим образом:
private DataModel<BookModel> books;
private BookModel currentBook;
public String view()
{
currentBook = books.getRowData();
return "bookview";
}
и в bookview.xhtml у меня есть это:
<h:dataTable value="#{BookBean.view}" var="item">
... // render content here
<h:dataTable>
но я получаю сообщение об ошибке о том, что свойство не найдено. Извините, что задаю этот вопрос, но я все еще не понимаю некоторых мощных функций JSF 2. Может быть, какой-нибудь эксперт, который понимает использование h:link
и getrowdata
, пожалуйста, объяснит мне в терминах непрофессионала или, возможно, с каким-нибудь базовым примером кода. Спасибо.
ОБНОВЛЕНИЕ: изменены классы на основе приведенных ниже предложений @BalusC. Класс BookModel является:
@Entity
public class BookModel implements Serializable
{
private Long id;
private String title;
private String author;
// getters and setters here
}
Класс BookService выглядит следующим образом:
@Stateless
public class BookService
{
@PersistenceContext(unitName = "persistentUnit")
protected EntityManager entityManager;
public BookModel create() {
return new BookModel();
}
public void delete(BookModel bookModel) {
bookModel = entityManager.merge(bookModel);
entityManager.remove(bookModel);
}
public BookModel update(BookModel bookModel) {
return entityManager.merge(bookModel);
}
public BookModel find(Long id) {
return entityManager.find(BookModel.class, id);
}
}
Класс BookBean является:
@ManagedBean(name = "bookBean")
@RequestScoped
public class BookBean implements Serializable
{
@EJB
private BookService bookService;
@ManagedProperty(value = "#{param.id}")
private Long id;
private DataModel<BookModel> books;
private BookModel currentBook;
@PostConstruct
public void init() {
currentBook = bookService.find(id);
}
public BookModel getCurrentBook() {
return currentBook;
}
public void setCurrentBook(BookModel currentBook) {
this.currentBook = currentBook;
}
}
Запуск класса BookBean, описанного выше, вызвал эту ошибку: java.lang.IllegalStateException: WEB9031: WebappClassLoader unable to load resource [org.apache.openjpa.util.LongId], because it has not yet been started, or was already stopped
. На данный момент я застрял именно на этом.
К вашему сведению: моя среда разработки — Glassfish 3.1, Apache OpenJPA 2.1 и JSF 2.1.0 (поставляется в комплекте с Glassfish)
Комментарии:
1. Я понятия не имею, что вы имеете в виду под «статусом CSS» и в чем именно заключается проблема. CSS — это просто язык стилизации, который никоим образом не должен влиять на функциональность JSF. Не могли бы вы, пожалуйста, пояснить?
2. @BalusC: CSS-статус , о котором я упоминал выше, связан с a:visited . Я надеюсь, что это прояснит любое недоразумение. 🙂
Ответ №1:
В коде есть два недостатка:
-
h:link
Запускает запрос GET, а не POST-запрос.DataModel#getRowData()
Здесь также бесполезно, поскольку вы не можете присоединять действия компонента к компонентам, которые запускают запрос GET. -
<h:dataTable value="#{BookBean.view}">
Сpublic String view()
не имеет смысла. Значение datatable должно быть набором элементов, а не методом действия компонента.
Я понимаю, что вы хотите получить ссылку на каждый элемент книги в таблице, которая указывает на некоторую страницу сведений об элементе книги. Исправьте страницу сведений следующим образом:
bookview.xhtml
<h:outputText value="#{bookBean.currentBook.id}" />
<h:outputText value="#{bookBean.currentBook.author}" />
<h:outputText value="#{bookBean.currentBook.title}" />
...
И BookBean
следующим образом:
@ManagedBean
@RequestScoped
public BookBean {
@ManagedProperty(value="#{param.id}")
private Long id;
private BookModel currentBook;
@PostConstruct
public void init() {
currentBook = bookDAO.find(id);
}
// ...
}
@ManagedProperty
Будет установлен параметр запроса GET. @PostConstruct
Будет предварительно загружена нужная книга на основе параметра.
Пожалуйста, обратите внимание, что это не имеет ничего общего с шаблоном получения ПОСЛЕ перенаправления.
Комментарии:
1. Отличный ответ! Хотя вопрос был очень неясным. @user463053 — Взгляните на BaluC balusc.blogspot.com/2010/06 /… опубликуйте отличный пример CRUD. Особенно для правильного использования getRowData(). @BaluC — Кстати, говоря о статусе CSS, я полагаю, он имел в виду теги привязки, к которым ко всем его ссылкам применяется стиль a: visited.
2. @BalusC: Да, вы правильно поняли, чего я хочу достичь. Я попробовал предложенные вами изменения выше, и я столкнулся с этой ошибкой:
java.lang.IllegalStateException: WEB9031: WebappClassLoader unable to load resource [org.apache.openjpa.util.LongId], because it has not yet been started, or was already stopped
. Извините, я должен был упомянуть, что я использую OpenJPA в своем первоначальном сообщении. Я обновил свой первоначальный пост дополнительной информацией, чтобы показать вам, что я пытаюсь сделать.3. @BalusC: Я удалил тег post-redirect-get и обновил сообщение другими тегами, которые, я надеюсь, более тесно связаны с моим вопросом.
4. Согласно вашей правке, очистите / перестройте / повторно разверните / перезапустите ваше веб-приложение / сервер.
5. @BalusC: Я закрываю Eclipse, удаляю каталог сборки проекта, удаляю каталог проекта в
eclipseApps
каталоге Glassfish, запускаю Eclipse, создаю проект, запускаю Glassfish — но все та же ошибка. Согласно моему обновлению выше,id
это первичный ключ, который, я думаю, требуется дляEntityManager#find
метода. Может ли это быть проблемой OpenJPA? Я также выполнил поиск по сообщению об ошибке, но ничего полезного не появилось.