2

ファイルのアップロードにrich:fileUploadを使用するページがあります。小さいファイルの場合、これは問題なく機能しますが、大きいファイル(+ 80MB)の場合、通常、ViewExpiredExceptionが発生します。私はすでに解決策を探そうとしましたが、これを解決するものは何も見つかりませんでした。

  • Richfaces 3.3.3.3
  • Tomcat 6.0.20
  • 春2.5.6
  • JSF 1.2_14

ページビーン:

@Component
@Scope("request")
public class Bean {
    ...
}

jspx:

<?xml version="1.0" encoding="UTF-8" ?>
<jsp:root omit-xml-declaration="true"
xmlns:jsp="http://java.sun.com/JSP/Page"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:t="http://myfaces.apache.org/tomahawk"
xmlns:a4j="https://ajax4jsf.dev.java.net/ajax"
xmlns:rich="http://richfaces.ajax4jsf.org/rich"
xmlns:ui="http://java.sun.com/jsf/facelets" version="2.0">
<rich:panel styleClass="formPanel">
    <h:form id="docForm">
        <ui:param name="doc" value="#{pb.newDoc}" />
    <h:panelGrid columns="2" columnClasses="formTableLabel, formTableField">
        ...
        <h:outputLabel for="fileUpload" value="#{labels['file']}*" />
    <h:panelGroup>
        <rich:fileUpload required="true" ajaxSingle="true"
            fileUploadListener="#{pb.uploadDocument}" id="fileUpload"
        autoclear="false" immediateUpload="true" noDuplicate="true"
        addControlLabel="#{labels['browse']}">
        <a4j:support event="onclear" reRender="fileUpload" ajaxSingle="true"
                oncomplete="$('docForm:fileUpload').component.currentInput.enable()"/>
        </rich:fileUpload>
        <h:message for="fileUpload" styleClass="errorMessage"
            showDetail="false" showSummary="true" />
    </h:panelGroup>
    ...

web.xml:

...
<context-param>
    <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
    <param-value>server</param-value>
</context-param>
<context-param>
    <param-name>facelets.SKIP_COMMENTS</param-name>
    <param-value>true</param-value>
</context-param>
<context-param>
    <param-name>facelets.BUFFER_SIZE</param-name>
    <param-value>500000</param-value>
</context-param>
<context-param>
    <param-name>org.richfaces.LoadScriptStrategy</param-name>
    <param-value>ALL</param-value>
</context-param>
<context-param>
    <param-name>org.richfaces.LoadStyleStrategy</param-name>
    <param-value>ALL</param-value>
</context-param>
<context-param>
    <param-name>javax.faces.DEFAULT_SUFFIX</param-name>
    <param-value>.jspx</param-value>
</context-param>
<context-param>
    <description>
        Context parameter specifically for facelets, lists available tag libraries.
    </description>
    <param-name>facelets.LIBRARIES</param-name>
    <param-value>
        /WEB-INF/taglibs/authorization.taglib.xml;
        /WEB-INF/taglibs/taskscreen.taglib.xml
    </param-value>
</context-param>
<context-param>
    <param-name>javax.faces.CONFIG_FILES</param-name>
    <param-value>/WEB-INF/config/faces-config.xml</param-value>
</context-param>
<context-param>
    <param-name>org.ajax4jsf.VIEW_HANDLERS</param-name>
    <param-value>com.sun.facelets.FaceletViewHandler</param-value>
</context-param>
<filter>
    <display-name>RichFaces Filter</display-name>
    <filter-name>richfaces</filter-name>
    <filter-class>org.ajax4jsf.Filter</filter-class>
    <init-param>
        <param-name>forceparser</param-name>
        <param-value>false</param-value>
    </init-param>
</filter>
<filter-mapping>
    <filter-name>Pretty Filter</filter-name>
    <servlet-name>Faces Servlet</servlet-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>richfaces</filter-name>
    <servlet-name>FacesServlet</servlet-name>
    <dispatcher>REQUEST</dispatcher>
    <dispatcher>FORWARD</dispatcher>
    <dispatcher>INCLUDE</dispatcher>
</filter-mapping>
<welcome-file-list>
    <welcome-file>start/start.jspx</welcome-file>
</welcome-file-list>
<error-page>
    <error-code>500</error-code>
    <location>/error.jspx</location>
</error-page>
<error-page>
    <error-code>403</error-code>
    <location>/access-denied.jspx</location>
</error-page>
<error-page>
    <exception-type>javax.faces.application.ViewExpiredException</exception-type>
    <location>/expired.jsf</location>
</error-page>
<session-config>
    <session-timeout>30</session-timeout>
</session-config>
...

スタックトレース:

SEVERE: JSF1054: (Phase ID: RESTORE_VIEW 1, View ID: ) Exception thrown during phase execution:   javax.faces.event.PhaseEvent[source=com.sun.faces.lifecycle.LifecycleImpl@22075431]
2012-09-13 16:43:46,945 [qtp130437654-18] ERROR org.ajax4jsf.webapp.BaseXMLFilter  doXmlFilter - Exception in the filter chain
javax.servlet.ServletException: viewId:/data/includes/doc.jspx - View /data/includes/doc.jspx could not be restored.
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:270)
at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:521)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1207)
at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:206)
at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:367)
at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:515)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1178)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:433)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:118)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:490)
at org.eclipse.jetty.server.session.SessionHandler.handle(SessionHandler.java:179)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:928)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:370)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:862)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:116)
at org.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:331)
at org.eclipse.jetty.server.Dispatcher.forward(Dispatcher.java:115)
at com.ocpsoft.pretty.PrettyFilter.doFilter(PrettyFilter.java:64)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1178)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:378)
at org.springframework.security.intercept.web.FilterSecurityInterceptor.invoke(FilterSecurityInterceptor.java:109)
at org.springframework.security.intercept.web.FilterSecurityInterceptor.doFilter(FilterSecurityInterceptor.java:83)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
at org.springframework.security.ui.SessionFixationProtectionFilter.doFilterHttp(SessionFixationProtectionFilter.java:67)
at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
at org.springframework.security.ui.ExceptionTranslationFilter.doFilterHttp(ExceptionTranslationFilter.java:101)
at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
at org.springframework.security.wrapper.SecurityContextHolderAwareRequestFilter.doFilterHttp(SecurityContextHolderAwareRequestFilter.java:91)
at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
at org.springframework.security.ui.AbstractProcessingFilter.doFilterHttp(AbstractProcessingFilter.java:278)
at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
at org.jasig.cas.client.session.SingleSignOutFilter.doFilter(SingleSignOutFilter.java:110)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
at org.springframework.security.ui.logout.LogoutFilter.doFilterHttp(LogoutFilter.java:89)
at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
at org.springframework.security.context.HttpSessionContextIntegrationFilter.doFilterHttp(HttpSessionContextIntegrationFilter.java:235)
at org.springframework.security.ui.SpringSecurityFilter.doFilter(SpringSecurityFilter.java:53)
at org.springframework.security.util.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:390)
at org.springframework.security.util.FilterChainProxy.doFilter(FilterChainProxy.java:175)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:236)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:167)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1178)
at com.doc.filter.IEFilter.doFilter(IEFilter.java:33)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1178)
at com.doc.portal.filter.ExceptionRedirectFilter.doFilter(ExceptionRedirectFilter.java:28)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1178)
at org.jasig.cas.client.session.SingleSignOutFilter.doFilter(SingleSignOutFilter.java:110)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1178)
at com.doc.filter.UTF8Filter.doFilter(UTF8Filter.java:20)
at org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1178)
at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:433)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:118)
at org.eclipse.jetty.security.SecurityHandler.handle(SecurityHandler.java:456)
at org.eclipse.jetty.server.session.SessionHandler.handle(SessionHandler.java:179)
at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:928)
at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:370)
at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:862)
at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:116)
at org.eclipse.jetty.server.handler.HandlerCollection.handle(HandlerCollection.java:126)
at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:115)
at org.eclipse.jetty.server.Server.handle(Server.java:330)
at org.eclipse.jetty.server.HttpConnection.handleRequest(HttpConnection.java:557)
at org.eclipse.jetty.server.HttpConnection$RequestHandler.content(HttpConnection.java:947)
at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:736)
at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:203)
at org.eclipse.jetty.server.HttpConnection.handle(HttpConnection.java:413)
at org.eclipse.jetty.server.bio.SocketConnector$Connection.run(SocketConnector.java:229)
at org.eclipse.jetty.server.ssl.SslSocketConnector$SslConnection.run(SslSocketConnector.java:648)
at org.eclipse.jetty.util.thread.QueuedThreadPool$2.run(QueuedThreadPool.java:435)
at java.lang.Thread.run(Thread.java:662)
Caused by: javax.faces.application.ViewExpiredException: viewId:/data/includes/doc.jspx - View /data/includes/doc.jspx could not be restored.
at com.sun.faces.lifecycle.RestoreViewPhase.execute(RestoreViewPhase.java:189)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
at com.sun.faces.lifecycle.RestoreViewPhase.doPhase(RestoreViewPhase.java:102)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:265)
... 75 more

誰かがこれを修正する方法について何かアイデアを持っていますか?どうも。

4

1 に答える 1

3

これは聞きたくないことかもしれませんが、標準の HTTP プロトコルは大きなファイルのアップロードではうまく機能しません。通常、ピア ツー ピア ソケット アプリケーションでは、クライアントとサーバーの両方が接続の正常性を維持し、大規模な転送中にすべてを有効に保つことができます。ただし、HTTP と Web では、クライアントが通常持っているステートフルなものは Cookie だけです。クライアントは、Cookie がサーバーに渡されて結果が返されるまで、Cookie がまだ有効かどうかを知ることができません(訂正: 特定の日付で有効期限が切れるように明示的に設定されていない限り) 。

このため、サーバーはセッションの存続期間にタイムラインを課す必要があり、その時間が経過すると、セッションのステートフル情報を破棄します。一般的なインターネット接続では、アップロード速度がダウンロード速度よりもやや遅くなる傾向があり、大きなファイルのアップロードを待っている間にセッションが無効になることは珍しくありません.

次の 3 つのオプションがあります。

  1. サーバー上のセッション タイムアウトの有効期限を増やします。おそらく、これで十分な時間が得られます。

  2. リッチ クライアント インターフェイス (Flash、アプレット、Silverlight など) を利用し、代わりにこれを介して Web ページにファイルをアップロードすることで、このリッチ クライアントを利用します。ここでの利点は、大きなファイルを管理しやすいバイナリ チャンクに分割し、セッション Cookie を使用して一度に 1 つずつサーバーに送信できることです。これらのチャンク リクエストが成功すると、転送中にセッションを維持する効果があります。最後のチャンクを受信した後、サーバーは大きなファイルを再構築して永続化できます。

  3. HTML5 と JS の機能を利用する以外は、基本的に #2 と同じことを行います。以下は、HTML5 テクノロジを利用して大きなファイルをチャンクに分割し、サーバー上での再構築を支援するオープン ソースの Javascript ライブラリです。http://steffentchr.dk/post/7454042318/resumable-js このアプローチの短所のいくつかは、HTML5 を使用しているため、最新のブラウザーでしか機能せず、IE7 などの古いブラウザーのサポートには疑問があることです。

ポイント 3 に関するもう 1 つの注意点は、この Javascript コードをカスタムまたは複合 JSF コンポーネント内に含めることは、クライアントとサーバー間のより合理化されたインターフェースを可能にする可能性の範囲外ではないということです。

また、次の質問も参照してください:非常に大きなファイルのアップロード

于 2012-09-14T11:28:12.407 に答える