Handling view parameters in JSF after post

后端 未结 2 448
无人共我
无人共我 2020-12-02 19:18

I have a few pages that needs a userId to work, thus the following code:

userpage.xhtml





        
相关标签:
2条回答
  • 2020-12-02 19:58

    Am I right that for solution 1 <f:ajax execute="@form" render="@form" /> to work one would also have to include something like

    <f:param name="userId" value="#{userPageController.userId}"/>
    

    inside the <h:commandButton>?

    Like it is described in https://stackoverflow.com/a/14026995/811046

    0 讨论(0)
  • 2020-12-02 20:11

    When i search around, I get the impression that the view parameter should remain after a post thus reading userpage.jsf?userId=123, but this is not the case. What is really the intended behaviour?

    This behaviour is correct. The <h:form> generates a HTML <form> element with an action URL without any view parameters. The POST request just submits to exactly that URL. If you intend to keep the view parameters in the URL, then there are basically 3 ways:

    1. Bring in some ajax magic.

      <h:commandButton action="#{userPageController.doAction}" value="post">
          <f:ajax execute="@form" render="@form" />
      </h:commandButton>
      

      This way the initially requested page and thus also the request URL in browser's address bar remains the same all the time.

    2. If applicable (e.g. for page-to-page navigation), make it a GET request and use includeViewParams=true. You can use <h:link> and <h:button> for this:

      <h:button outcome="nextview?includeViewParams=true" value="post" />
      

      However, this has an EL security exploit in Mojarra versions older than 2.1.6. Make sure that you're using Mojarra 2.1.6 or newer. See also issue 2247.

    3. Control the generation of action URL of <h:form> yourself. Provide a custom ViewHandler (just extend ViewHandlerWrapper) wherein you do the job in getActionURL().

      public String getActionURL(FacesContext context, String viewId) {
          String originalActionURL = super.getActionURL(context, viewId);
          String newActionURL = includeViewParamsIfNecessary(context, originalActionURL);
          return newActionURL;
      }
      

      To get it to run, register it in faces-config.xml as follows:

      <application>
          <view-handler>com.example.YourCustomViewHandler</view-handler>
      </application>
      

      This is also what OmniFaces <o:form> is doing. It supports an additional includeViewParams attribute which includes all view parameters in the form's action URL:

      <o:form includeViewParams="true">
      

    Update: obtaining the view parameters of the current view programmatically (which is basically your 2nd question) should be done as follows:

    Collection<UIViewParameter> viewParams = ViewMetadata.getViewParameters(FacesContext.getCurrentInstance().getViewRoot());
    
    for (UIViewParameter viewParam : viewParams) {
        String name = viewParam.getName();
        Object value = viewParam.getValue();
        // ...
    }
    
    0 讨论(0)
提交回复
热议问题