I try to use Richfaces DataTable with DataTableModel to have server side paging and sorting.
My tebaleModel is a spring bean with scope "request" and " proxyMode = ScopedProxyMode.TARGET_CLASS".
On the page is a keepAlive tag for tebaleModel bean.
When I click next the bean is initialized but it should be restored.
Can anybody help. I can provide the code if my question is not clear.
Update:
- My bean impelements Serializable, because SerializableDataModel which I extend implements Serializable
- is within a form
In another managedBean I have type if bean proxy and keepAlive works just fine. I don't use this for DataTableModel becasue it doesnt't work with this pattern.
Maybe if you see the code you notice what I done wrong.
Here is my code
ManagedBean:
@Component
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class UserTableDataModel extends SerializableDataModel implements Modifiable {
/**
*
*/
private static final long serialVersionUID = -4188575485838003516L;
@Autowired
private UserManager userManager;
private Long currentPk;
private Map<Long, User> wrappedData;
private List<Long> wrappedKeys;
private int pageSize;
private int pageNo;
private int pages;
private SortInfo sortInfo;
private List<SelectItem> pagesList;
@PostConstruct
public void init() {
wrappedKeys = null;
wrappedData = new HashMap<Long, User>();
pageSize = 1;
pageNo = 1;
pages = userManager.getUserCount() / pageSize;
pagesList = new ArrayList<SelectItem>();
for (int i = 1; i < pages + 1; i++) {
pagesList.add(new SelectItem(i));
}
}
@PreDestroy
public void clen(){
System.out.println("ddd");
}
/**
* Getter for pagesList.
*
* @return the pagesList
*/
public List<SelectItem> getPagesList() {
return pagesList;
}
@Override
public void update() {
}
@Override
public Object getRowKey() {
return this.currentPk;
}
@Override
public void setRowKey(Object key) {
this.currentPk = (Long) key;
}
@Override
public void walk(FacesContext context, DataVisitor visitor, Range range, Object argument) throws IOException {
int firstRow = ((SequenceRange) range).getFirstRow();
int numberOfRows = ((SequenceRange) range).getRows();
int pageNumber = firstRow / pageSize;
setPageNo(pageNumber + 1);
wrappedKeys = new ArrayList<Long>();
for (User item : userManager.getUsers(new PresentationInfo(new PageInfo(pageSize, pageNumber), sortInfo))) {
wrappedKeys.add(item.getId());
wrappedData.put(item.getId(), item);
visitor.process(context, item.getId(), argument);
}
}
@Override
public int getRowCount() {
return userManager.getUserCount();
}
@Override
public User getRowData() {
if (currentPk == null) {
return null;
} else {
User ret = wrappedData.get(currentPk);
if (ret == null) {
try {
ret = userManager.getUser(currentPk);
} catch (UserManagerBusinessException e) {
e.printStackTrace();
} catch (ValidationException e) {
e.printStackTrace();
}
wrappedData.put(currentPk, ret);
return ret;
} else {
return ret;
}
}
}
@Override
public int getRowIndex() {
// TODO Auto-generated method stub
return 0;
}
@Override
public Object getWrappedData() {
// TODO Auto-generated method stub
return null;
}
@Override
public boolean isRowAvailable() {
// TODO Auto-generated method stub
return true;
}
@Override
public void setRowIndex(int rowIndex) {
// TODO Auto-generated method stub
}
@Override
public void setWrappedData(Object data) {
// TODO Auto-generated method stub
}
public SerializableDataModel getSerializableModel(Range range) {
SerializableDataModel model = null;
if (wrappedKeys != null) {
model = this;
}
return model;
}
/**
* Getter for pageSize.
*
* @return the pageSize
*/
public int getPageSize() {
return pageSize;
}
/**
* Setter for pageSize.
*
* @param pageSize the pageSize to set
*/
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
/**
* Getter for pageNo.
*
* @return the pageNo
*/
public int getPageNo() {
return pageNo;
}
/**
* Setter for pageNo.
*
* @param pageNo the pag开发者_JS百科eNo to set
*/
public void setPageNo(int pageNo) {
this.pageNo = pageNo;
}
/**
* Getter for pages.
*
* @return the pages
*/
public int getPages() {
return pages;
}
@Override
public void modify(List<FilterField> filterFields, List<SortField2> sortFields) {
if (sortFields != null && !sortFields.isEmpty()) {
sortInfo = new SortInfo();
for (SortField2 sf : sortFields) {
Ordering order = sf.getOrdering();
String exp = sf.getExpression().getExpressionString();
String fieldName = exp.substring(exp.indexOf('.') + 1, exp.indexOf('}'));
if (Ordering.ASCENDING.equals(order)) {
sortInfo.addSortFieldAscending(fieldName);
} else {
sortInfo.addSortFieldDescending(fieldName);
}
}
}
}
}
web page userTable.xhtml:
<ui:composition 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"
template="/templates/mainTemplate.xhtml">
<ui:param name="bean" value="${userTableDataModel}" />
<ui:define name="mainPage">
<h:form id="${commonBean.mainFormName}">
<a4j:keepAlive beanName="userTableDataModel" />
<h:panelGrid columns="1" columnClasses="top , top">
<rich:dataTable id="table" value="#{bean}" var="user" width="580px"
rows="#{bean.pageSize}" sortMode="multi" selectionMode="single">
<f:facet name="header">
<h:outputText value="${userMsg.users}" />
</f:facet>
<rich:column sortable="true" label="${userMsg.firstName}"
sortBy="#{user.firstName}">
<f:facet name="header">
<h:outputText value="${userMsg.firstName}" />
</f:facet>
<h:outputText value="#{user.firstName}" />
</rich:column>
<rich:column label="${userMsg.lastName}" sortable="true"
sortBy="#{user.lastName}">
<f:facet name="header">
<h:outputText value="${userMsg.lastName}" />
</f:facet>
<h:outputText value="#{user.lastName}" />
</rich:column>
<rich:column sortable="true" sortBy="#{user.login}"
label="${userMsg.login}">
<f:facet name="header">
<h:outputText value="${userMsg.login}" />
</f:facet>
<h:outputText value="#{user.login}" />
</rich:column>
<f:facet name="footer">
<rich:datascroller maxPages="#{bean.pages}" fastControls="hide"
page="#{bean.pageNo}" pagesVar="pages" id="ds">
<f:facet name="first">
<h:outputText value="First" styleClass="scrollerCell" />
</f:facet>
<f:facet name="first_disabled">
<h:outputText value="First" styleClass="scrollerCell" />
</f:facet>
<f:facet name="last">
<h:outputText value="Last" styleClass="scrollerCell" />
</f:facet>
<f:facet name="last_disabled">
<h:outputText value="Last" styleClass="scrollerCell" />
</f:facet>
<f:facet name="previous">
<h:outputText value="Previous" styleClass="scrollerCell" />
</f:facet>
<f:facet name="previous_disabled">
<h:outputText value="Previous" styleClass="scrollerCell" />
</f:facet>
<f:facet name="next">
<h:outputText value="Next" styleClass="scrollerCell" />
</f:facet>
<f:facet name="next_disabled">
<h:outputText value="Next" styleClass="scrollerCell" />
</f:facet>
<f:facet name="pages">
<h:panelGroup>
<h:outputText value="Page " />
<h:selectOneMenu value="#{bean.pageNo}"
onchange="#{rich:component('ds')}.switchToPage(this.value)">
<f:selectItems value="#{bean.pagesList}" />
</h:selectOneMenu>
<h:outputText value=" of #{pages}" />
</h:panelGroup>
</f:facet>
</rich:datascroller>
</f:facet>
</rich:dataTable>
</h:panelGrid>
</h:form>
</ui:define>
</ui:composition>
- Your bean has to implement
Serializable - the
<a4j:keepAlive>should be within a form - Try adding
<f:view>around - As a sidenote, you'd better make all your spring dependencies (the classes injected into the managed bean)
transient, and then restore them from the spring context inreadResolve. Serializing the whole hierarchy of injected beans, potentially with proxies might be cumbersome.
The work around is to do the interface which is implemented by the model and provided a method to return model itselft. Then everything is working fine.
加载中,请稍侯......
精彩评论