Details

    • Type: Bug Bug
    • Status: Open
    • Priority: Critical Critical
    • Resolution: Unresolved
    • Affects Version/s: 2.1
    • Fix Version/s: None
    • Component/s: Components/Renderers
    • Labels:
      None

      Description

      As every UIInput component, UIViewParameter normally retains its value after a postback. If there's any kind of validation error on the page (unrelated to the UIViewParameter) the model to which the UIViewParameter is bound will correctly not be updated. However, when the component is subsequently encoded this model will be queried for its value.

      In effect, the retained value is typically lost when the model is in request scope.

      The following reproduces this:

      viewparam.xhtml
      <html xmlns="http://www.w3.org/1999/xhtml"
          xmlns:h="http://java.sun.com/jsf/html"
          xmlns:f="http://java.sun.com/jsf/core"
      >
      
          <f:metadata>
              <f:viewParam id="id" name="id" value="#{viewParamBean.id}"/>
          </f:metadata>
      
          <h:body>
      
              <h:messages />
      
              #{viewParamBean.id} <br/>
      
              <h:form>
                  <h:inputText value="#{viewParamBean.text}" >
                      <f:validateLength minimum="2"/>
                  </h:inputText>
      
                  <h:commandButton value="test" action="#{viewParamBean.actionMethod}"/>
              </h:form>
      
          </h:body>
      </html>
      
      ViewParamBean.java
      @ManagedBean
      @RequestScoped
      public class ViewParamBean {
      
          private long id;    
          private String text;
      
          public void actionMethod() {
      
          }
      
          public long getId() {
              return id;
          }
      
          public void setId(long id) {
              this.id = id;
          }
      
          public String getText() {
              return text;
          }
      
          public void setText(String text) {
              this.text = text;
          }    
      }
      

      If you call the Facelet with viewparam.xhtml?id=12 it will display the 12 onscreen. If you then input something valid, e.g. aaaaa, the id will disappear from the URL, but keeps being displayed on screen (owning to the stateful nature of ui components). As soon as any validator error occurs (e.g. entering a), the id will be permanently lost. Entering valid input afterwards will not bring it back.

      The implementation of encodeAll of UIViewParameter in Mojarra highlights what's happening:

      UIViewParameter.java
      public void encodeAll(FacesContext context) throws IOException {
          if (context == null) {
              throw new NullPointerException();
          }
      
          // if there is a value expression, update view parameter w/ latest value after render
          // QUESTION is it okay that a null string value may be suppressing the view parameter value?
          // ANSWER: I'm not sure.
          setSubmittedValue(getStringValue(context));
      }
      
      public String getStringValue(FacesContext context) {
          String result = null;
          if (hasValueExpression()) {
              result = getStringValueFromModel(context);
          } else {
              result = (null != rawValue) ? rawValue : (String) getValue();
          }
          return result;
      }
      

      Because hasValueExpression() in getStringValue() is true, this will try to get the value from the model. But in case the model is request scoped it will not have any value for this request, since validation has just failed and thus no value has ever been set. In effect, the stateful value of UIViewParameter is overwritten by whatever the model returns as a default (typically null, but this depends on the model of course).

      Expected behavior: After validation errors occur, the model should not be consulted (e.g. as implemented by Mojarra's HtmlBasicRenderer#getCurrentValue)

        Activity

        arjan tijms created issue -
        Ed Burns made changes -
        Field Original Value New Value
        Assignee rogerk [ rogerk ]
        Ed Burns made changes -
        Fix Version/s 2.3 [ 16372 ]
        Hide
        Ed Burns added a comment -

        Set priority to baseline ahead of JSF 2.3 triage. Priorities will be assigned accurately after this exercise.

        Show
        Ed Burns added a comment - Set priority to baseline ahead of JSF 2.3 triage. Priorities will be assigned accurately after this exercise.
        Ed Burns made changes -
        Priority Major [ 3 ] Trivial [ 5 ]
        Fix Version/s 2.3 [ 16372 ]
        Manfred Riem made changes -
        Priority Trivial [ 5 ] Critical [ 2 ]
        Hide
        Manfred Riem added a comment -

        Setting priority to Critical

        Show
        Manfred Riem added a comment - Setting priority to Critical
        Manfred Riem made changes -
        Assignee arjan tijms [ arjan_t ]

          People

          • Assignee:
            arjan tijms
            Reporter:
            arjan tijms
          • Votes:
            15 Vote for this issue
            Watchers:
            15 Start watching this issue

            Dates

            • Created:
              Updated: