我有一个页面范围的组件,它有一个带有数据的实例变量List,我在数据表中显示。该数据表具有分页,排序和过滤功能。
第一次进入页面时,我会在网址中附加此内容:?conversationId = 97 。页面正常工作,当我更改数据表页面时,现在没有创建组件。
一两分钟后,在随机的随机时间,我得到一个例外,说没有上下文。我没有在我的代码或导航文件中使用@Create。
所以,我有两个问题:
干杯!
更新I:
该项目是一个耳朵。
这是页面:
<!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:ui="http://java.sun.com/jsf/facelets"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:a4j="http://richfaces.org/a4j"
xmlns:rich="http://richfaces.org/rich">
<body>
<ui:composition template="/WEB-INF/facelets/templates/template.xhtml">
<ui:define name="content">
<!-- This method returns focus on the filter -->
<script type="text/javascript">
function submitByEnter(event){
if (event.keyCode == 13) {
if (event.preventDefault) {
// Firefox
event.preventDefault();
} else {
// IE
event.returnValue = false;
}
document.getElementById("refreshButton").click();
}
}
</script>
<h:form prependId="false">
<h:commandButton action="Back" value="Back to home page" />
<br />
<p><h:outputText
value="Applicants and Products (experimentation page)"
class="page_title" /></p>
<h:commandButton
action="#{applicantProductListBean.showCreateApplicant}"
value="Create Applicant" id="createApplicantButton">
</h:commandButton>
<a4j:commandButton value="Refresh" id="refreshButton"
action="#{applicantProductListBean.refreshData}"
image="/images/icons/refresh48x48.gif"
reRender="compositeTable, compositeScroller">
<!-- <f:setPropertyActionListener-->
<!-- target="# {pageScrollerBean.applicantProductListPage}" value="1" />-->
</a4j:commandButton>
<rich:toolTip for="createApplicantButton" value="Create Applicant" />
<rich:dataTable styleClass="composite2DataTable" id="compositeTable"
rows="1" columnClasses="col"
value="#{applicantProductListBean.dataModel}" var="pageAppList">
<f:facet name="header">
<rich:columnGroup>
<rich:column colspan="3">
<h:outputText styleClass="headerText" value="Applicants" />
</rich:column>
<rich:column colspan="3">
<h:outputText styleClass="headerText" value="Products" />
</rich:column>
<rich:column breakBefore="true">
<h:outputText styleClass="headerText" value="Applicant Name" />
<a4j:commandButton id="sortingApplicantNameButton"
action="#{applicantProductListBean.toggleSorting('applicantName')}"
image="/images/icons/sorting/#{sortingFilteringBean.applicantProductListSorting.sortingValues['applicantName']}.gif"
reRender="sortingApplicantNameButton, sortingApplicantEmailButton, compositeTable, compositeScroller">
<!-- <f:setPropertyActionListener-->
<!-- target="#{pageScrollerBean.applicantProductListPage}" value="1" />-->
</a4j:commandButton>
<br />
<h:inputText
value="#{sortingFilteringBean.applicantProductListFiltering.filteringValues['applicantName']}"
id="applicantNameFilterValue"
onkeypress="return submitByEnter(event)">
</h:inputText>
</rich:column>
<rich:column>
<h:outputText styleClass="headerText" value="Applicant Email" />
<a4j:commandButton id="sortingApplicantEmailButton"
action="#{applicantProductListBean.toggleSorting('applicantEmail')}"
image="/images/icons/sorting/#{sortingFilteringBean.applicantProductListSorting.sortingValues['applicantEmail']}.gif"
reRender="sortingApplicantNameButton, sortingApplicantEmailButton, compositeTable, compositeScroller">
<!-- <f:setPropertyActionListener-->
<!-- target="#{pageScrollerBean.applicantProductListPage}" value="1" />-->
</a4j:commandButton>
<br />
<h:inputText
value="#{sortingFilteringBean.applicantProductListFiltering.filteringValues['applicantEmail']}"
id="applicantEmailFilterValue"
onkeypress="return submitByEnter(event)">
</h:inputText>
</rich:column>
<rich:column>
<h:outputText styleClass="headerText" value="Applicant Actions" />
</rich:column>
<rich:column>
<h:outputText styleClass="headerText" value="Product Name" />
<a4j:commandButton id="sortingProductNameButton"
action="#{applicantProductListBean.toggleSorting('productName')}"
immediate="true"
image="/images/icons/sorting/#{sortingFilteringBean.applicantProductListSorting.sortingValues['productName']}.gif"
reRender="sortingProductNameButton, compositeTable, compositeScroller">
</a4j:commandButton>
<br />
<h:inputText
value="#{sortingFilteringBean.applicantProductListFiltering.filteringValues['productName']}"
id="productNameFilterValue"
onkeypress="return submitByEnter(event)">
</h:inputText>
</rich:column>
<rich:column>
<h:outputText styleClass="headerText" value="Product Email" />
<br />
<h:inputText
value="#{sortingFilteringBean.applicantProductListFiltering.filteringValues['productEmail']}"
id="productEmailFilterValue"
onkeypress="return submitByEnter(event)">
</h:inputText>
</rich:column>
<rich:column>
<h:outputText styleClass="headerText" value="Product Actions" />
</rich:column>
</rich:columnGroup>
</f:facet>
<rich:subTable rowClasses="odd_applicant_row, even_applicant_row"
value="#{pageAppList}" var="app">
<rich:column
styleClass=" internal_cell
composite2TextContainingColumn"
valign="top">
<h:outputText value="#{app.name}" />
</rich:column>
<rich:column
styleClass="internal_cell composite2TextContainingColumn"
valign="top">
<h:outputText value="#{app.receiptEmail}" />
</rich:column>
<rich:column valign="top" styleClass="buttonsColumn">
<h:commandButton
action="#{applicantProductListBean.showUpdateApplicant(app)}"
image="/images/icons/edit.jpg">
</h:commandButton>
<!-- <rich:toolTip for="editApplicantButton" value="Edit Applicant" />-->
<h:commandButton
action="#{applicantProductListBean.showDeleteApplicant(app)}"
image="/images/icons/delete.png">
</h:commandButton>
<!-- <rich:toolTip for="deleteApplicantButton" value="Delete Applicant" />-->
</rich:column>
<rich:column colspan="3">
<table class="productsTableTable">
<tbody>
<tr>
<td class="createProductButtonTableCell"><h:commandButton
action="#{applicantProductListBean.showCreateProduct(app)}"
value="Create Product">
</h:commandButton>
<!-- <rich:toolTip for="createProductButton" value="Create Product" />-->
</td>
</tr>
<tr>
<td><rich:dataTable value="#{app.products}" var="prod"
rowClasses="odd_product_row, even_product_row">
<rich:column
styleClass="internal_cell composite2TextContainingColumn">
<h:outputText value="#{prod.inventedName}" />
</rich:column>
<rich:column
styleClass="internal_cell composite2TextContainingColumn">
<h:outputText value="#{prod.receiptEmail}" />
</rich:column>
<rich:column styleClass="buttonsColumn">
<h:commandButton
action="#{applicantProductListBean.showUpdateProduct(prod)}"
image="/images/icons/edit.jpg">
</h:commandButton>
<!-- <rich:toolTip for="editProductButton" value="Edit Product" />-->
<h:commandButton
action="#{applicantProductListBean.showDeleteProduct(prod)}"
image="/images/icons/delete.png">
<f:setPropertyActionListener target="#{productBean.product}"
value="#{prod}" />
</h:commandButton>
<!-- <rich:toolTip for="deleteProductButton" value="Delete Product" />-->
</rich:column>
</rich:dataTable></td>
</tr>
</tbody>
</table>
</rich:column>
</rich:subTable>
<f:facet name="footer">
<h:panelGrid columns="1" styleClass="applicantProductListFooter">
<h:outputText value="#{msgs.no_results}" rendered="#{(empty applicantProductListBean.dataModel) || (applicantProductListBean.dataModel.rowCount==0)}"/>
<rich:datascroller align="center" for="compositeTable"
page="#{pageScrollerBean.applicantProductListPage}"
id="compositeScroller" reRender="compositeTable"
renderIfSinglePage="false" fastControls="hide">
<f:facet name="first">
<h:outputText value="#{msgs.first}" styleClass="scrollerCell" />
</f:facet>
<f:facet name="first_disabled">
<h:outputText value="#{msgs.first}" styleClass="scrollerCell" />
</f:facet>
<f:facet name="last">
<h:outputText value="#{msgs.last}" styleClass="scrollerCell" />
</f:facet>
<f:facet name="last_disabled">
<h:outputText value="#{msgs.last}" styleClass="scrollerCell" />
</f:facet>
<f:facet name="next">
<h:outputText value="#{msgs.next}" styleClass="scrollerCell" />
</f:facet>
<f:facet name="next_disabled">
<h:outputText value="#{msgs.next}" styleClass="scrollerCell" />
</f:facet>
<f:facet name="previous">
<h:outputText value="#{msgs.previous}" styleClass="scrollerCell" />
</f:facet>
<f:facet name="previous_disabled">
<h:outputText value="#{msgs.previous}" styleClass="scrollerCell" />
</f:facet>
</rich:datascroller>
</h:panelGrid>
</f:facet>
</rich:dataTable>
</h:form>
</ui:define>
这是支持bean:
@Name("applicantProductListBean")
@Scope(ScopeType.PAGE)
public class ApplicantProductListBean extends
BasePagedSortableFilterableListBean {
/**
* Public field for ad-hoc injection to work.
*/
@EJB(name = "FacadeService")
public ApplicantFacadeService applicantFacadeService;
@Logger
private static Log logger;
private final int pageSize = 10;
@Out(scope = ScopeType.CONVERSATION, required = false)
Applicant currentApplicant;
@Out(scope = ScopeType.CONVERSATION, required = false)
Product product;
@Create
public void onCreate() {
System.out.println("Create");
}
@Override
protected DataModel initDataModel(int pageSize) {
// get filtering and sorting from session
sorting = getSorting();
filtering = getFiltering();
// System.out.println("Initializing a Composite3DataModel");
// System.out.println("Pagesize: " + pageSize);
// System.out.println("Filtering: " + filtering.getFilteringValues());
// System.out.println("Sorting: " + sorting.getSortingValues());
return new Composite3DataModel(1, sorting, filtering);
}
// Navigation methods
/**
* Navigation-returning method, returns the action to follow after pressing
* the "Create Applicant" button
*
* @return the action to be taken
*/
public Navigation.ApplicantProductList showCreateApplicant() {
return Navigation.ApplicantProductList.SHOW_CREATE_APPLICANT;
}
/**
* Navigation-returning method, returns the action to follow after pressing
* the "Edit Applicant" button
*
* @return the action to be taken
*/
public Navigation.ApplicantProductList showUpdateApplicant(
Applicant applicant) {
this.currentApplicant = applicant;
return Navigation.ApplicantProductList.SHOW_UPDATE_APPLICANT;
}
/**
* Navigation-returning method, returns the action to follow after pressing
* the "Delete Applicant" button
*
* @return the action to be taken
*/
public Navigation.ApplicantProductList showDeleteApplicant(
Applicant applicant) {
this.currentApplicant = applicant;
return Navigation.ApplicantProductList.SHOW_DELETE_APPLICANT;
}
/**
* Navigation-returning method, returns the action to follow after pressing
* the "Create Product" button
*
* @return the action to be taken
*/
public Navigation.ApplicantProductList showCreateProduct(Applicant app) {
this.product = new Product();
this.product.setApplicant(app);
return Navigation.ApplicantProductList.SHOW_CREATE_PRODUCT;
}
/**
* Navigation-returning method, returns the action to follow after pressing
* the "Edit Product" button
*
* @return the action to be taken
*/
public Navigation.ApplicantProductList showUpdateProduct(Product prod) {
this.product = prod;
return Navigation.ApplicantProductList.SHOW_UPDATE_PRODUCT;
}
/**
* Navigation-returning method, returns the action to follow after pressing
* the "Delete Product" button
*
* @return the action to be taken
*/
public Navigation.ApplicantProductList showDeleteProduct(Product prod) {
this.product = prod;
return Navigation.ApplicantProductList.SHOW_DELETE_PRODUCT;
}
/**
* */
@Override
public Sorting getSorting() {
if (sorting == null) {
return (getSortingFilteringBeanFromSession()
.getApplicantProductListSorting());
}
return sorting;
}
/**
*
*/
@Override
public void setSorting(Sorting sorting) {
getSortingFilteringBeanFromSession().setApplicantProductListSorting(
sorting);
}
/**
*
*/
@Override
public Filtering getFiltering() {
if (filtering == null) {
return (getSortingFilteringBeanFromSession()
.getApplicantProductListFiltering());
}
return filtering;
}
/**
*
*/
@Override
public void setFiltering(Filtering filtering) {
getSortingFilteringBeanFromSession().setApplicantProductListFiltering(
filtering);
}
/**
* @return the currentApplicant
*/
public Applicant getCurrentApplicant() {
return currentApplicant;
}
/**
* @param currentApplicant
* the currentApplicant to set
*/
public void setCurrentApplicant(Applicant applicant) {
this.currentApplicant = applicant;
}
/**
* The model for this page
*
*/
private class Composite3DataModel extends
PagedSortableFilterableDataModel<List<Applicant>> {
public Composite3DataModel(int pageSize, Sorting sorting,
Filtering filtering) {
super(pageSize, sorting, filtering);
}
@Override
protected DataPage<List<Applicant>> fetchPage(int fakeStartRow,
int fakePageSize) {
// if (logger.isTraceEnabled()) {
System.out.println("Getting page with fakeStartRow: " + fakeStartRow
+ " and fakePageSize " + fakePageSize);
// }
// to find the page size multiply the startRow and the fakePageSize
// (which is 1) to the actual page size
int startRow = fakeStartRow
* ApplicantProductListBean.this.pageSize;
int pageSize = fakePageSize
* ApplicantProductListBean.this.pageSize;
// if (logger.isTraceEnabled()) {
System.out.println("Getting page with startRow: " + startRow
+ " and pageSize " + pageSize);
// }
List<Applicant> pageApplicants = applicantFacadeService
.findPagedWithCriteria(startRow, pageSize, filtering,
sorting);
// List<Applicant> pageApplicants = applicantFacadeService
// .findPagedWithDynamicQuery(startRow, pageSize, filtering,
// sorting, true);
// if (logger.isTraceEnabled()) {
System.out.println("Set of applicants: " + pageApplicants.size());
// }
List<List<Applicant>> pageApplicantsListContainer = new ArrayList<List<Applicant>>();
pageApplicantsListContainer.add(pageApplicants);
DataPage<List<Applicant>> dataPage = new DataPage<List<Applicant>>(
this.getRowCount(), fakeStartRow,
pageApplicantsListContainer);
return dataPage;
}
@Override
protected int getDatasetSize() {
// int size = getServiceFacade().countWithCriteria(filtering,
// sorting);
// int size =
// applicantFacadeService.countWithDynamicQuery(filtering, sorting,
// false);
int size = (int) Math.ceil((double) applicantFacadeService
.countWithCriteria(filtering, sorting, false)
/ pageSize);
if (logger.isTraceEnabled()) {
logger.trace("Got Dataset Size: " + size);
}
return size;
}
}
/**
* @return the product
*/
public Product getProduct() {
return product;
}
/**
* @param product
* the product to set
*/
public void setProduct(Product product) {
this.product = product;
}
}
这是页面文件(请注意,只要我不离开页面就不会创建对话):
<?xml version="1.0" encoding="UTF-8"?>
<page>
<navigation>
<rule if-outcome="Back">
<redirect view-id="/index.xhtml" />
</rule>
<rule if-outcome="SHOW_CREATE_PRODUCT">
<begin-conversation join="true" />
<redirect view-id="/pages/product/createProduct.xhtml" />
</rule>
<rule if-outcome="SHOW_UPDATE_PRODUCT">
<begin-conversation join="true" />
<redirect view-id="/pages/product/editProduct.xhtml" />
</rule>
<rule if-outcome="SHOW_DELETE_PRODUCT">
<begin-conversation join="true" />
<redirect view-id="/pages/product/deleteProduct.xhtml" />
</rule>
<rule if-outcome="SHOW_CREATE_APPLICANT">
<begin-conversation join="true" />
<redirect view-id="/pages/applicant/createApplicant.xhtml" />
</rule>
<rule if-outcome="SHOW_UPDATE_APPLICANT">
<begin-conversation join="true" />
<redirect view-id="/pages/applicant/editApplicant.xhtml" />
</rule>
<rule if-outcome="SHOW_DELETE_APPLICANT">
<begin-conversation join="true" />
<redirect view-id="/pages/applicant/deleteApplicant.xhtml" />
</rule>
</navigation>
</page>
更新II:
stacktrace是here
答案 0 :(得分:4)
好吧,让我们看看
第一次进入页面时,我会在网址中附加此内容:?conversationId = 97
确定。如Seam in Action书中所述
默认情况下,Seam会创建一个临时对话来为当前请求提供服务。在呈现响应之后,在恢复视图阶段之后紧接着初始化 被销毁相。
和
一两分钟后,在随机的随机时间,我得到一个例外,说没有上下文。
每个会话都有自己的超时期限,默认为全局超时设置
/WEB-INF/components.xml
<core:manager conversation-timeout="1000000"/>
或特定于页面的
<page view-id="/app.xhtml" timeout="1000000"/>
其值以毫秒为单位。但必须超过在web.xml中定义的会话超时
/WEB-INF/web.xml
<!--specified in minutes-->
<session-config>
<session-timeout>30</session-timeout>
</session-config>
也许它解释了为什么你会得到你的例外。
但是如果你真的想知道你是否有长时间的对话,Seam会存储一个名为对话的内置对话范围组件。所以在您的托管bean 中,执行以下操作以了解您是否有长时间运行的对话
org.jboss.seam.core.Conversation conversation = (Conversation) Component.getInstance("conversation");
System.out.println(conversation.isLongRunning());
如果您看到 true ,那么您已开始长时间对话。您甚至可以在页面内看到
#{conversation.longRunning}
我希望它对你有用。
答案 1 :(得分:0)
尝试制作组件范围的对话而不是页面。听起来你想做的事情比页面范围更大,它只保留一个请求的上下文。
我不确定你为什么把这个conversationId参数附加到你的网址上。然而,接缝中的所有通信都发生在对话中。如果其页面作用域,则会话是临时会话。要将对话提升为长时间运行的对话,您需要开始注释或在pages.xml中启动对话。
我认为seamBooking示例应用程序有一些示例代码应该与您尝试的类似。