ICEfaces
  1. ICEfaces
  2. ICE-9234

Ability to specify Exception types and redirect values for Ajax responses

    Details

    • Type: Improvement Improvement
    • Status: Closed
    • Priority: Major Major
    • Resolution: Fixed
    • Affects Version/s: 3.3
    • Fix Version/s: 4.0
    • Component/s: Bridge
    • Labels:
      None
    • Environment:
      JSF
    • Assignee Priority:
      P3
    • Affects:
      Documentation (User Guide, Ref. Guide, etc.)

      Description

      JavaEE applications can specify a location for the container to redirect to when an exception is detected on the server. This is done in the web.xml using:

      <error-page>
          <exception-type>org.mycompany.myproduct.MyException</exception-type>
          <location>error.html</location>
      </error-page>>

      However, this does not work when using JSF with Ajax. Any exceptions are propagated back to the client as part of the Ajax response so the container never sees them.

      ICEfaces has a feature where you can specify a context parameter:

      <context-param>
          <param-name>org.icefaces.sessionExpiredRedirectURI</param-name>
          <param-value>error.html</param-value>
      </context-param>

      However, this only applies to a single use case. If the exception is not specifically an org.icefaces.application.SessionExpiredException, nothing will happen. This can be a problem if a session expiry leads to a different exception. I recommend looking at ICE-9224 for additional details about this issue.

      This JIRA recommends that the current ICEfaces feature be expanded to allow developers to declare multiple exceptions and redirection locations - basically providing the same functionality as error-page declarations but that would work with Ajax responses.

        Activity

        Hide
        Mircea Toma added a comment -

        Implemented redirect on exception feature. The URLs used for redirection can be absolute or relative. The relative URLs are resolved by ViewHandler.getResourceURL method.

        Show
        Mircea Toma added a comment - Implemented redirect on exception feature. The URLs used for redirection can be absolute or relative. The relative URLs are resolved by ViewHandler.getResourceURL method.
        Hide
        Mircea Toma added a comment - - edited

        The mappings between the thrown exceptions and the URLs that the browser should be redirected to are to be defined as the value of the newly introduced org.icefaces.redirectOnExceptionMapping context parameter.
        Here's an example:

            <context-param>
                <param-name>org.icefaces.redirectOnExceptionMapping</param-name>
                <param-value>
                    org.icefaces.demo.FirstException::http://yahoo.com/
                    org.icefaces.demo.SecondException::/login.jsf
                    org.icefaces.demo.ThirdException::summary.jsf
                </param-value>
            </context-param>
        

        As you can see the full qualified class name of the exception is separated by the corresponding redirect URI by two colons ::. Also each mapping is separated by empty space (such as \n).

        Show
        Mircea Toma added a comment - - edited The mappings between the thrown exceptions and the URLs that the browser should be redirected to are to be defined as the value of the newly introduced org.icefaces.redirectOnExceptionMapping context parameter. Here's an example: <context-param> <param-name> org.icefaces.redirectOnExceptionMapping </param-name> <param-value> org.icefaces.demo.FirstException::http://yahoo.com/ org.icefaces.demo.SecondException::/login.jsf org.icefaces.demo.ThirdException::summary.jsf </param-value> </context-param> As you can see the full qualified class name of the exception is separated by the corresponding redirect URI by two colons :: . Also each mapping is separated by empty space (such as \n ).
        Hide
        Krashan Brahmanjara added a comment - - edited

        I can't confirm this behavior on Ice 4 rev. 41336.

        In real app with this configuration

        <context-param><!-- previous solution-->
        <param-name>org.icefaces.sessionExpiredRedirectURI</param-name>
        <param-value>'closed.jsp'</param-value>
        </context-param>
        <context-param>
        <param-name>org.icefaces.redirectOnExceptionMapping</param-name>
        <param-value>
        org.icefaces.application.SessionExpiredException::/closed.jsp?sessionExpired
        java.lang.Throwable::/error.iface
        </param-value>
        </context-param>
        <context-param>
        <param-name>org.icefaces.blockUIOnSubmit</param-name>
        <param-value>true</param-value>
        </context-param>
        <context-param>
        <param-name>org.icefaces.disableDefaultErrorPopups</param-name>
        <param-value>true</param-value>
        </context-param>
        <context-param>
        <param-name>org.icefaces.strictSessionTimeout</param-name>
        <param-value>true</param-value>
        </context-param>
        <context-param>
        <param-name>org.icefaces.warnBeforeSessionExpiryInterval</param-name>
        <param-value>20</param-value>
        </context-param>
        <session-config>
        <session-timeout>1</session-timeout>
        </session-config>
        <login-config>
        <form-login-config>
        <form-login-page>/login.jsp</form-login-page>
        <form-error-page>/login.jsp</form-error-page>
        </form-login-config>
        </login-config>

        After timeout SessionExpiredListener.sessionDestroyed is executed but doesn't work as in original comment

        //If the session is destroyed and ICEpush is available, we can request a push request immediately
        //which should result in a SessionExpiredException being sent to the client.

        ExtendedExceptionHandler.handle is called with this line too "new SessionExpiredException("session expired (causing view to expire)"));" ...but SessionExpiredException isn't catched with new handler

        Finally any push button action in browser after session timeout send "partial/ajax" request and response has HTTP 200 status and login page in body response but browser do not show this page ...body catched by ajax engine?
        Also next responses on blocked browser /listen.icepush.xml.iface has got response X-Connection=close
        and X-Connection-reason=duplicate without any message on redirection to login page.

        For web.xml settings changed to

        <context-param>
        <param-name>org.icefaces.disableDefaultErrorPopups</param-name>
        <param-value>true</param-value>
        </context-param>

        only standard ajax boxes with "User Session Expired" and warnBeforeSessionExpiry appears.
        ... not any redirection to redirectOnExceptionMapping as expected.

        Show
        Krashan Brahmanjara added a comment - - edited I can't confirm this behavior on Ice 4 rev. 41336. In real app with this configuration <context-param><!-- previous solution--> <param-name>org.icefaces.sessionExpiredRedirectURI</param-name> <param-value>'closed.jsp'</param-value> </context-param> <context-param> <param-name>org.icefaces.redirectOnExceptionMapping</param-name> <param-value> org.icefaces.application.SessionExpiredException::/closed.jsp?sessionExpired java.lang.Throwable::/error.iface </param-value> </context-param> <context-param> <param-name>org.icefaces.blockUIOnSubmit</param-name> <param-value>true</param-value> </context-param> <context-param> <param-name>org.icefaces.disableDefaultErrorPopups</param-name> <param-value>true</param-value> </context-param> <context-param> <param-name>org.icefaces.strictSessionTimeout</param-name> <param-value>true</param-value> </context-param> <context-param> <param-name>org.icefaces.warnBeforeSessionExpiryInterval</param-name> <param-value>20</param-value> </context-param> <session-config> <session-timeout>1</session-timeout> </session-config> <login-config> <form-login-config> <form-login-page>/login.jsp</form-login-page> <form-error-page>/login.jsp</form-error-page> </form-login-config> </login-config> After timeout SessionExpiredListener.sessionDestroyed is executed but doesn't work as in original comment //If the session is destroyed and ICEpush is available, we can request a push request immediately //which should result in a SessionExpiredException being sent to the client. ExtendedExceptionHandler.handle is called with this line too "new SessionExpiredException("session expired (causing view to expire)"));" ...but SessionExpiredException isn't catched with new handler Finally any push button action in browser after session timeout send "partial/ajax" request and response has HTTP 200 status and login page in body response but browser do not show this page ...body catched by ajax engine? Also next responses on blocked browser /listen.icepush.xml.iface has got response X-Connection=close and X-Connection-reason=duplicate without any message on redirection to login page. For web.xml settings changed to <context-param> <param-name>org.icefaces.disableDefaultErrorPopups</param-name> <param-value>true</param-value> </context-param> only standard ajax boxes with "User Session Expired" and warnBeforeSessionExpiry appears. ... not any redirection to redirectOnExceptionMapping as expected.
        Hide
        Krashan Brahmanjara added a comment -

        Above solution also do not catch this kind of errors and small error box appears

        at org.apache.myfaces.view.facelets.compiler.CheckDuplicateIdFaceletUtils.checkIds(CheckDuplicateIdFaceletUtils.java:89)
        at org.apache.myfaces.view.facelets.DefaultFaceletsStateManagementStrategy.saveView(DefaultFaceletsStateManagementStrategy.java:663)
        at org.apache.myfaces.application.StateManagerImpl.saveView(StateManagerImpl.java:213)
        at javax.faces.application.StateManager.getViewState(StateManager.java:262)
        at org.icefaces.impl.context.DOMPartialViewContext.renderState(DOMPartialViewContext.java:740)
        at org.icefaces.impl.context.DOMPartialViewContext.processPartial(DOMPartialViewContext.java:300)
        at javax.faces.component.UIViewRoot.encodeChildren(UIViewRoot.java:516)

        Show
        Krashan Brahmanjara added a comment - Above solution also do not catch this kind of errors and small error box appears at org.apache.myfaces.view.facelets.compiler.CheckDuplicateIdFaceletUtils.checkIds(CheckDuplicateIdFaceletUtils.java:89) at org.apache.myfaces.view.facelets.DefaultFaceletsStateManagementStrategy.saveView(DefaultFaceletsStateManagementStrategy.java:663) at org.apache.myfaces.application.StateManagerImpl.saveView(StateManagerImpl.java:213) at javax.faces.application.StateManager.getViewState(StateManager.java:262) at org.icefaces.impl.context.DOMPartialViewContext.renderState(DOMPartialViewContext.java:740) at org.icefaces.impl.context.DOMPartialViewContext.processPartial(DOMPartialViewContext.java:300) at javax.faces.component.UIViewRoot.encodeChildren(UIViewRoot.java:516)

          People

          • Assignee:
            Mircea Toma
            Reporter:
            Deryk Sinotte
          • Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved: