Redirect to same page with changed viewParam

Splash Forums Rewrite Users Redirect to same page with changed viewParam

This topic contains 5 replies, has 2 voices, and was last updated by  Christian Kaltepoth 1 year, 7 months ago.

Viewing 6 posts - 1 through 6 (of 6 total)
  • Author
    Posts
  • #26590

    fkoentopp
    Participant

    Hello,

    I have a problem with a redirect to the same view with a changed viewParam:

    view.xhtml:

    
    ...
      <f:metadata>
        <o:viewParam id="viewParamObservationDate" name="observationDate" value="#{bean.observationDate}" converter="jodaDateTimeConverter" />
      </f:metadata>
    
      <o:form id="formObservationFilter" includeViewParams="true">
        <p:selectBooleanCheckbox id="checkboxObservationDate" value="#{bean.observationDateActive}">
          <p:ajax event="change" listener="#{bean.applyObservationDateActive}" />
        </p:selectBooleanCheckbox>
      </o:form>
    ...
    

    Bean:

    
    ...
    @Named
    @ViewScoped
    public class Bean {
        public void applyObservationDateActive() throws IOException {
            if (this.observationDateActive) {
                this.setObservationDate(DateTime.now());
            } else {
                this.setObservationDate(null);
            }
    
            final FacesContext context = FacesContext.getCurrentInstance();
            final NavigationHandler navigationHandler = context.getApplication().getNavigationHandler();
            navigationHandler.handleNavigation(context, null, "refresh");
        }
    }
    ...
    

    Navigation-Rule:

    
    ...
      <navigation-rule>
        <from-view-id>view.xhtml</from-view-id>
        <navigation-case>
          <from-outcome>refresh</from-outcome>
          <to-view-id>view.xhtml</to-view-id>
          <redirect include-view-params="true" />
        </navigation-case>
      </navigation-rule>
    ...
    

    Here is my problem:

    When the view is opened the first time, the URL is correct, which means there is no observationDate as URL parameter as the checkbox is also unchecked. When the checkbox is clicked, the observationDate will be set and the redirect will be made and after that the URL is changed with the correct parameter.

    But when the checkbox is now unchecked and the redirect will be made, the old parameter still exists after the view is loaded. After debugging I found out, that the RewriteViewHandler#getActionURL(...) method calls the DefaultActionUrlProvider#getActionURL(...) method which returns FacesRewriteLifecycleListener.getOriginalRequestURL(request). And here is the problem, in this URL the parameter, which has been set to null before the redirect, is still existent. Later on in the MultiViewHandler from JSF, where the default parameter work is done and added to the action url, the parameter is correctly not added, because it has been set to null.

    Am I missing something, or how can I delete a view param value?

    Greetings
    Fabian

    #26651

    Hmmm. Interesting issue.

    It is correct that RewriteViewHandler#getActionURL(...) will basically return the requested URL. This is done because the form should post back to the same rewritten URL and not to the plain JSF URL. But I don’t see how this could cause the problem you are describing.

    I’ll try to summarize what happens:

    1. You request the page WITH the view parameter, so the checkbox will be checked.
    2. You uncheck the checkbox which will trigger a postback to the same URL that was originally requested (WITH the view parameter)
    3. Your code triggers a redirect with “include-view-params=true” which will include the view parameters with the current values.

    As far as I can tell the problem is in step 3. And I don’t think that Rewrite is involved here, is it? Or is RewriteViewHandler#getActionURL(...) called here?

    Wouldn’t it solve your problem if you clear the bean property bound to the view parameter in step #3?

    #26658

    fkoentopp
    Participant

    Hi,

    thanks for the answer. Actually in step 2, I am clearing the bean property:

    @Named
    @ViewScoped
    public class Bean {
        public void applyObservationDateActive() throws IOException {
            if (this.observationDateActive) {
                this.setObservationDate(DateTime.now());
            } else {
                this.setObservationDate(null);
            }
    
            final FacesContext context = FacesContext.getCurrentInstance();
            final NavigationHandler navigationHandler = context.getApplication().getNavigationHandler();
            navigationHandler.handleNavigation(context, null, "refresh");
        }
    }

    And in step 3 which is then triggered in navigationHandler.handleNavigation(context, null, "refresh") the Rewrite method RewriteViewHandler#getActionURL(...) is called, yes.

    #26660

    Hmmm. Interesting. I’m not sure why RewriteViewHandler#getActionURL(...) is called during navigation. Could you provide a stacktrace from the debugger?

    #26666

    fkoentopp
    Participant

    I attached the stacktrace.

    Attachments:
    1. stacktrace.txt
    #26671

    Hmmmmm. It’s difficult to tell what is going wrong here. There are many things interacting here. The JSF implementation, Omnifaces, Rewrite and perhaps others. IMO it is correct that Rewrite returns the URL with the query parameter from getActionURL() as the parameter was present in the incoming request. That is correct in regard to the JSF spec. I don’t fully understand why MultiViewHandler.getRedirectURL() is calling getActionURL(). This doesn’t make sense to me. But anyway, the JSF implementation should handle includeViewParams correctly. And if the JSF implementation uses getActionURL() for some reason, it should also remove view parameters if required.

Viewing 6 posts - 1 through 6 (of 6 total)

You must be logged in to reply to this topic.

Comments are closed.