为Primefaces数据列表实现LazyModel时发生异常
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了为Primefaces数据列表实现LazyModel时发生异常相关的知识,希望对你有一定的参考价值。
我正在尝试为素数数据列表实现类似于here所示的数据表的延迟加载模型。
我的初始代码具有正常的AJAX分页功能,效果很好。但是,当我尝试使用延迟加载模型时,页面加载时会出现以下异常:
com.sun.faces.application.view.FaceletViewHandlingStrategy handleRenderException
SEVERE: Error Rendering View[/pages/index.xhtml]
java.io.NotSerializableException: java.util.ArrayList$SubList
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1180)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1493)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1493)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
at java.util.HashMap.writeObject(HashMap.java:1100)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:975)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1528)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1493)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1362)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1170)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
at java.util.HashMap.writeObject(HashMap.java:1100)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:601)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:975)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1480)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1416)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1174)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:346)
at com.sun.faces.renderkit.ClientSideStateHelper.doWriteState(ClientSideStateHelper.java:325)
at com.sun.faces.renderkit.ClientSideStateHelper.writeState(ClientSideStateHelper.java:173)
at com.sun.faces.renderkit.ResponseStateManagerImpl.writeState(ResponseStateManagerImpl.java:122)
at com.sun.faces.application.StateManagerImpl.writeState(StateManagerImpl.java:166)
at com.sun.faces.application.view.WriteBehindStateWriter.flushToWriter(WriteBehindStateWriter.java:225)
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:418)
at com.sun.faces.application.view.MultiViewHandler.renderView(MultiViewHandler.java:131)
at com.sun.faces.lifecycle.RenderResponsePhase.execute(RenderResponsePhase.java:121)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:139)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:594)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:472)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:929)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:407)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1002)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:585)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:310)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1110)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:603)
at java.lang.Thread.run(Thread.java:722)
这里是index.html]的代码>
<!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:p="http://primefaces.org/ui"> <ui:composition template="/pages/templates/template.xhtml"> <ui:define name="content"> <h:form prependId="false" id="form"> <p:dataList value="#{movies.lazyMovieModel}" var="movie" id="movies" paginator="true" rows="10" paginatorTemplate="{FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}" type="none" paginatorAlwaysVisible="false" lazy="true"> <h:outputText value="#{movie.movieName}, #{movie.releaseYear}" style="margin-left:10px"> </h:outputText> <br/> </p:dataList> </h:form> </ui:define> </ui:composition> </html>
MovieListBean.java
(LazyModel实现)import org.primefaces.model.LazyDataModel; import com.clixflix.enitities.Movie; import com.clixflix.jsf.extensions.LazyMovieDataModel; @ManagedBean(name = "movies") @ViewScoped public class MovieListBean extends BaseBean implements Serializable { private static final long serialVersionUID = -5719443344065177588L; private LazyDataModel<Movie> lazyMovieModel; @PostConstruct public void initialize() { lazyMovieModel = new LazyMovieDataModel(); } public LazyDataModel<Movie> getLazyMovieModel() { List<Movie> movieList = getServiceLocator().getMovieService().getMovieList(); ((LazyMovieDataModel) lazyMovieModel).setMovieList(movieList); return lazyMovieModel; } }
LazyMovieDataModel.java
public class LazyMovieDataModel extends LazyDataModel<Movie> { private static final long serialVersionUID = 8745562148994455749L; private List<Movie> movieList; public LazyMovieDataModel() { this.movieList = Collections.emptyList(); } @Override public List<Movie> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) { // Sorting if (null != sortField) { LazySorter sorter = new LazySorter(sortField, sortOrder); Collections.sort(movieList, sorter); sorter = null; } // RowCount int rowCount = movieList.size(); this.setRowCount(rowCount); // Pagination if (rowCount > pageSize) { return movieList.subList(first, (first + pageSize)); } else { return movieList; } } private class LazySorter implements Comparator<Movie> { private String sortField; private SortOrder sortOrder; LazySorter(String sortField, SortOrder sortOrder) { this.sortField = sortField; this.sortOrder = sortOrder; } @SuppressWarnings("unchecked") @Override public int compare(Movie movie1, Movie movie2) { Object value1 = null, value2 = null; try { value1 = Movie.class.getField(this.sortField).get(movie1); value2 = Movie.class.getField(this.sortField).get(movie2); int value = ((Comparable<Object>) value1).compareTo(value2); return SortOrder.ASCENDING.equals(sortOrder) ? value : -1 * value; } catch (IllegalArgumentException | IllegalAccessException | NoSuchFieldException | SecurityException e) { e.printStackTrace(); return 0; } } } public void setMovieList(List<Movie> movieList) { this.movieList = movieList; } }
我假设这是例外:
return movieList.subList(first, (first + pageSize));
有人可以指导我我想念什么吗?
而且,我在日志中观察到,当我使用lazymodel时,将查询数据库DB [[3次
,但是当我使用普通的AJAX分页时,将查询DB [仅一次:|UPDATE
:我弄清楚了查询数据库3次的原因。这是因为我在LazyModel的getter中而不是仅在load方法中调用我的服务。我在课程中进行了以下更改:LazyMovieDataModel.java
public class LazyMovieDataModel extends LazyDataModel<Movie>
{
private static final long serialVersionUID = 8745562148994455749L;
public LazyMovieDataModel() {}
@Override
public List<Movie> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, String> filters) {
List<Movie> movieList = getServiceLocator().getMovieService().getMovieList(first, (first + pageSize));
// RowCount
int rowCount = ((Number)getServiceLocator().getMovieService().getMovieCount()).intValue();
this.setRowCount(rowCount);
}
}
MovieListBean.java中的LazyModel getter
/* Removed PostConstruct init method */
public LazyDataModel<Movie> getLazyMovieModel()
{
return lazyMovieModel;
}
以上更改在初始页面加载时工作正常。但是,当我单击下一页按钮(或任何分页按钮)时,在加载方法中会得到getServiceLocator()
的NPE。[serviceLocator是从BaseBean继承并使用Spring注入的
protected
访问权限修改的托管属性。
getter在后续调用中返回null的任何原因?
我正在尝试为素数数据列表实现类似于本文所示数据表的延迟加载模型。我的初始代码具有正常的AJAX分页功能,可以正常工作。但是,...
答案
ArrayList $ SubList是一个问题。返回的subList没有实现可序列化。尝试使用:return new ArrayList(movieList.subList(first, (first + pageSize)));
另一答案
此link中存在相同问题。LazyDataModel中有2种加载方法:以上是关于为Primefaces数据列表实现LazyModel时发生异常的主要内容,如果未能解决你的问题,请参考以下文章
JSF / PrimeFaces使用selectOneMenu将列表中的项目关联起来