【问题标题】:How do I exclude servlet-filters from having to be serialized?如何将 servlet-filters 排除在序列化之外?
【发布时间】:2013-05-02 23:22:02
【问题描述】:

我刚刚将我的 Beans 转换为 ViewScoped 而不是 RequestScoped。但是,由于我必须将 Serialized 添加到这些 bean 中,所以我得到了两个 java.io.NotSerializableException 异常。

这是我的web.xml

<filter>
  <filter-name>PrimeFaces FileUpload Filter</filter-name>
  <filter-class>org.primefaces.webapp.filter.FileUploadFilter</filter-class>
</filter>
<filter>
   <filter-name>loginFilter</filter-name>
   <filter-class>com.company.rews.webclient.controller.LoginFilter</filter-class>
</filter>

<servlet>
  <servlet-name>Faces Servlet</servlet-name>
  <servlet-class>com.company.rews.webclient.controller.MyFacesServletWrapper</servlet-class>
  <load-on-startup>1</load-on-startup>
</servlet>

它报告这个异常的第一个地方是super.service(req, res)

public class MyFacesServletWrapper extends MyFacesServlet 
{

@Override
public void service(ServletRequest request, ServletResponse response)
        throws IOException, ServletException
{
    HttpServletRequest req = (HttpServletRequest) request;
    HttpServletResponse res = (HttpServletResponse) response;        

    req.setCharacterEncoding("UTF-8");
    res.setCharacterEncoding("UTF-8");        

    try
    {   
        super.service(req, res);        
    }
    catch (ServletException e)
    {           
        e.printStackTrace();
        LoginFilter.gotoLogin(e, req, res);
    }        
}

}

这里是chain.doFilter(request, response)

public class LoginFilter implements Filter
{
 private static final String SYSTEM_ERROR_URI = "/login.faces";
 private static final String VIEWEX_ERROR_URI = "/login.faces";

@Override
public void doFilter( ServletRequest req, ServletResponse res, FilterChain chain ) throws IOException, ServletException
{

    HttpServletRequest  request  = (HttpServletRequest) req;
    HttpServletResponse response = (HttpServletResponse) res;

    if ( isResourceRequest(request, response) )
    {
        chain.doFilter(request, response);
    }
    else if ( !isLoggedIn(request, response) && isLoginArea(request, response) )
    {
        gotoLogin(null, request, response);
    }
    else if( !isUserConnectedToREWS( request ) && isLoginArea(request, response) )
    {
        gotoLogin(null, request, response);
    }
    else
    {
        chain.doFilter(request, response);
    }

}

这是完整的错误报告:

08.05.2013. 18:03:47 org.apache.myfaces.renderkit.ServerSideStateCacheImpl serializeView
SEVERE: Exiting serializeView - Could not serialize state: org.apache.myfaces.context.servlet.ServletExternalContextImpl
java.io.NotSerializableException: org.apache.myfaces.context.servlet.ServletExternalContextImpl
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1164)
at java.io.ObjectOutputStream.defaultWriteFields(ObjectOutputStream.java:1518)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1483)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
at java.util.HashMap.writeObject(HashMap.java:1001)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1469)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1346)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1154)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
at java.util.HashMap.writeObject(HashMap.java:1001)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at java.io.ObjectStreamClass.invokeWriteObject(ObjectStreamClass.java:945)
at java.io.ObjectOutputStream.writeSerialData(ObjectOutputStream.java:1469)
at java.io.ObjectOutputStream.writeOrdinaryObject(ObjectOutputStream.java:1400)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1158)
at java.io.ObjectOutputStream.writeArray(ObjectOutputStream.java:1346)
at java.io.ObjectOutputStream.writeObject0(ObjectOutputStream.java:1154)
at java.io.ObjectOutputStream.writeObject(ObjectOutputStream.java:330)
at org.apache.myfaces.renderkit.ServerSideStateCacheImpl.serializeView(ServerSideStateCacheImpl.java:390)
at org.apache.myfaces.renderkit.ServerSideStateCacheImpl.saveSerializedViewInServletSession(ServerSideStateCacheImpl.java:240)
at org.apache.myfaces.renderkit.ServerSideStateCacheImpl.saveSerializedView(ServerSideStateCacheImpl.java:872)
at org.apache.myfaces.renderkit.html.HtmlResponseStateManager.saveState(HtmlResponseStateManager.java:144)
at org.apache.myfaces.application.StateManagerImpl.saveView(StateManagerImpl.java:195)
at org.apache.myfaces.view.facelets.FaceletViewDeclarationLanguage.renderView(FaceletViewDeclarationLanguage.java:1971)
at org.apache.myfaces.application.ViewHandlerImpl.renderView(ViewHandlerImpl.java:285)
at org.apache.myfaces.lifecycle.RenderResponseExecutor.execute(RenderResponseExecutor.java:115)
at org.apache.myfaces.lifecycle.LifecycleImpl.render(LifecycleImpl.java:241)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:199)
at org.apache.myfaces.webapp.MyFacesServlet.service(MyFacesServlet.java:112)
at com.mainconcept.rews.webclient.controller.MyFacesServletWrapper.service(MyFacesServletWrapper.java:30)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:305)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:79)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at com.company.rews.webclient.controller.LoginFilter.doFilter(LoginFilter.java:54)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:225)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:169)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:168)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:98)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:927)
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:999)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:565)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:307)
at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
at java.lang.Thread.run(Thread.java:662)

如果这是这里的问题,我如何排除 servlet-filters 必须被序列化?

【问题讨论】:

  • 您究竟为什么认为org.apache.myfaces.context.servlet.ServletExternalContextImpl 是您的过滤器之一?它只是 MyFaces 的 ExternalContext 实现,当您在 servlet 环境(而不是 portlet 环境)上运行 JSF 时使用它。这反过来表明您在某处错误地将 ExternalContext 分配为需要可序列化的支持 bean 的属性。
  • 顺便说一句,MyFacesServletWrapper 正在做的工作最好通过过滤器来完成。
  • 好的,我让班级成员FacesContext 成为transient,现在它可以工作了。我仍然不确定这是否是正确的做法......?也许我可以将FacesContext 设为静态或...?
  • 您应该永远将其设为实例变量。它的生命周期为一个 HTTP 请求。你绝对不应该让它成为一个寿命比这个更长的类的实例变量。

标签: jsf servlets servlet-filters


【解决方案1】:

停止将FacesContextExternalContext 及其所有工件分配为实例变量。您应该始终、始终在线程本地范围内(即在方法块内)获取和分配它们。

另见:


请注意,这一切都与 servlet 过滤器无关

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-23
    • 1970-01-01
    • 2013-04-12
    • 2010-11-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多