我正在尝试在我的应用程序中使用自定义ViewHandler,该应用程序使用JSF2,PrimeFaces 3.2.x构建并部署在Glassfish AS v3.1.1上。一旦我在faces-config.xml中添加了自定义ViewHandler,第一页就可以正常呈现,但任何操作都会导致NPE。我修改了我的ViewHandler,所以除了代理父ViewHandler之外什么也没做,但问题仍然存在。
CustomViewHandler的代码
import java.io.IOException;
import java.util.Locale;
import javax.faces.FacesException;
import javax.faces.application.ViewHandler;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
public class CustomViewHandler extends ViewHandler {
private ViewHandler parent;
public CustomViewHandler(ViewHandler parent) {
this.parent = parent;
}
@Override
public UIViewRoot restoreView(FacesContext facesContext, String viewId) {
return parent.restoreView(facesContext, viewId);
}
@Override
public Locale calculateLocale(FacesContext facesContext) {
return parent.calculateLocale(facesContext);
}
@Override
public String calculateRenderKitId(FacesContext facesContext) {
return parent.calculateRenderKitId(facesContext);
}
@Override
public UIViewRoot createView(FacesContext facesContext, String viewId) {
return parent.createView(facesContext, viewId);
}
@Override
public String getActionURL(FacesContext facesContext, String actionId) {
return parent.getActionURL(facesContext, actionId);
}
@Override
public String getResourceURL(FacesContext facesContext, String resId) {
return parent.getResourceURL(facesContext, resId);
}
@Override
public void renderView(FacesContext facesContext, UIViewRoot viewId) throws IOException, FacesException {
parent.renderView(facesContext, viewId);
}
@Override
public void writeState(FacesContext facesContext) throws IOException {
parent.writeState(facesContext);
}
public ViewHandler getParent() {
return parent;
}
}
我的faces-config.xml
<application>
<view-handler>com.util.CustomViewHandler</view-handler>
<message-bundle>messages</message-bundle>
<locale-config>
<default-locale>en</default-locale>
<supported-locale>en</supported-locale>
</locale-config>
<resource-bundle>
<base-name>messages</base-name>
<var>msg</var>
</resource-bundle>
</application>
堆栈跟踪
java.lang.NullPointerException
at javax.faces.component.UIComponentBase.getRenderer(UIComponentBase.java:1402)
at javax.faces.component.UIComponentBase.decode(UIComponentBase.java:785)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1181)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1176)
at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1176)
at javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:933)
at com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.java:78)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:593)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1539)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:343)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:79)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
at com.seer.filter.CharacterEncodingFilter.doFilter(CharacterEncodingFilter.java:21)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:256)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:217)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardPipeline.doInvoke(StandardPipeline.java:655)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:595)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:98)
at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:91)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:162)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:330)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:231)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:232)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:828)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:725)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:1019)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:225)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:137)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:104)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:90)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:79)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:54)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:59)
at com.sun.grizzly.ContextTask.run(ContextTask.java:71)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:532)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:513)
at java.lang.Thread.run(Thread.java:722)
由于
答案 0 :(得分:2)
我遇到了同样的错误,但是通过扩展ViewHandlerWrapper
而不是ViewHandler
来解决错误。
以下是我CustomViewHandler
的示例(不是一个完整的示例,但是在我们的应用程序中构建为概念证明):
import javax.faces.application.ViewExpiredException;
import javax.faces.application.ViewHandler;
import javax.faces.application.ViewHandlerWrapper;
import javax.faces.component.UIViewRoot;
import javax.faces.context.FacesContext;
import org.apache.log4j.Logger;
public class CustomViewHandler extends ViewHandlerWrapper {
private ViewHandler wrapped;
private static Logger LOGGER = Logger.getLogger(CustomViewHandler.class);
public CustomViewHandler(ViewHandler wrapped) {
LOGGER.info("CustomViewHandler.CustomViewHandler():wrapped View Handler:"+wrapped.getClass());
this.wrapped = wrapped;
}
@Override
public UIViewRoot restoreView(FacesContext context, String viewId) {
UIViewRoot root;
try {
LOGGER.info("restoring view : " + viewId);
root = wrapped.restoreView(context, viewId);
} catch (ViewExpiredException e) {
LOGGER.error("View Expired : " + e.getMessage() + " -> recreating");
root = wrapped.createView(context, viewId);
}
return root;
}
@Override
public ViewHandler getWrapped() {
return wrapped;
}
}
如果您想要一个更完整且功能更强的自定义视图处理程序,请查看OmniFaces
RestorableViewHandler。源代码可在该页面上找到。
javax.faces.application.ViewHandlerWrapper
提供ViewHandler的简单实现,可以由希望为现有ViewHandler实例提供专门行为的开发人员进行子类化。所有方法的默认实现是调用包装的ViewHandler。
用法:扩展此类并覆盖getWrapped以返回我们正在包装的实例。