jsr372-experts@javaserverfaces-spec-public.java.net

[jsr372-experts] Re: [jsr372-experts mirror] Re: Re: Re: Re: [1433-UIInputRequiredTrue] PROPOSAL

From: Neil Griffin <neil.griffin_at_portletfaces.org>
Date: Tue, 6 Dec 2016 15:43:27 -0500

If JAVASERVERFACES_SPEC_PUBLIC-1433 is adopted, then would anyone object to backporting this to the JSF 2.2 and 2.1 API source? My best guess is that it would be necessary to enable it with a com.sun.faces/org.apache.myfaces global web config param in 2.2/2.1 unless we did an MR.

> On Dec 6, 2016, at 2:08 AM, Bauke Scholtz <balusc_at_gmail.com> wrote:
>
> Hi,
>
> For menus, radios and manycheckboxes, nothing will change as well. For booleancheckbox, it will fix the unintuitive behavior of a required=true to not have any effect.
>
> Cheers, B
>
>
> On Tue, Dec 6, 2016, 05:34 Leonardo Uribe <leonardo.uribe_at_irian.at> wrote:
> Hi
>
> NG>> Getting back to my main question, can we simply change:
>
>
> if (submittedValue == null) {
> return;
> }
>
> NG>> To this: (without a check for a global web config param)
>
>
> if ((submittedValue == null) && !isRequired()) {
> return;
> }
>
> NG>> Or will that cause a backward compatibility problem?
>
> As far as I know, request parameter values are never interpreted as null,
> because if it is present, the value is filled with an empty string.
>
> The javadoc of ServletRequest.setAttribute says this:
>
> "... If the object passed in is null, the effect is the same as calling
> removeAttribute(java.lang.String). ..."
>
> So the answer is the change does not cause a backward compatibility
> problem, and based on that the web config parameter is not really
> necessary. Does it work in all cases? I'm not 100% sure, because we need
> to check what happens for menu/radio/checkbox, but if that so, apply a
> simple patch with just these lines could be a valid solution.
>
> regards,
>
> Leonardo Uribe
>
> 2016-12-02 14:19 GMT-05:00 Bauke Scholtz <balusc_at_gmail.com>:
> +1 for avoiding context param and enforcing required=true regardless of submittedValue. But really nothing more than that.
>
> Cheers, B
>
>
> On Fri, Dec 2, 2016, 19:29 Neil Griffin <neil.griffin_at_portletfaces.org> wrote:
> Hi again everyone,
>
> LU >> the case where "no value was submitted for this component" is underspecified
>
> @Leonardo: +1 I think that you have identified an oversight in the Spec language. Also, I agree with you that we should avoid a global web config param if possible.
>
> LU >> If the value is not submitted [...] and required flag is set to true, validation
> LU >> should fail, no questions asked, without exceptions
>
> @Leonardo: +1 I think that you are exactly right. If required="true", shouldn't the JSF developer be able to rely on the PROCESS_VALIDATIONS phase to enforce that? The plain meaning would be that the value is *always* required, without qualification or exception.
>
> @All: Also, consider the case of a custom Captcha type of component with a built-in validator:
>
> <my:inputCaptcha required="true" value="#{myBean.captcha}" />
>
> public abstract class InputCaptcha extends UIInput {
>
> @Override
> protected void validateValue(FacesContext context, Object value) {
>
> // Call super in order enforce required="true"
> super.validateValue(context, value);
>
> if (isValid()) {
> // Determine if captcha was typed correctly by the user
> ...
> }
> }
> ...
> }
>
> Given the current Spec language, if the Captcha's <input type="text" /> is removed from the DOM prior to the postback, validateValue(FacesContext,Object) will not be called, and server-side validation will be bypassed for the Captcha component.
>
> Getting back to my main question, can we simply change:
>
> if (submittedValue == null) {
> return;
> }
>
> To this: (without a check for a global web config param)
>
> if ((submittedValue == null) && !isRequired()) {
> return;
> }
>
> Or will that cause a backward compatibility problem?
>
>
> Best Regards to all,
>
> Neil
>
> > On Dec 1, 2016, at 9:43 PM, Leonardo Uribe <leonardo.uribe_at_irian.at> wrote:
> >
> > Hi
> >
> > BS>> Yes, but this indicaties a bad model. The normal solution would be to put
> > BS>> a @NotNull constraint on the entity or a NOT NULL constraint on the column.
> >
> > BS>> Here's a related Stack Overflow post of mine on the subject:
> >
> > I agree from a conceptual perspective, but from a technical/syntax perspective I
> > disagree. In fact, I'm concern about this. The reason is the validation is
> > bound to the input component, not to the button or the action, even with
> > Bean Validation. So, even if you have a @NotNull, the problem is the
> > validation bypass, which is not obvious and will happen anyway. In other
> > words @NotNull will not solve the problem.
> >
> > In the taglib javadoc of h:inputSecret, h:inputText and h:inputTextarea about
> > "required" says this:
> >
> > "... Flag indicating that the user is required to provide a submitted value for
> > this input component. ..."
> >
> > If the value is not submitted (decode does not call setSubmitted()) and required
> > flag is set to true, validation should fail, no questions asked, without
> > exceptions. The reason is if the component is "executed", it is expected to
> > have a submitted value, otherwise the request is invalid.
> >
> > The problem is there is a confusion between "required" attribute and
> > RequiredValidator or @NotNull.
> >
> > JSF 2.2 section 3.5.4 says this:
> >
> > "... The render-independent property required is a shorthand for the function
> > of a "required" validator. If the value of this property is true and the
> > component has no value, the component is marked invalid and a message is added
> > to the FacesContext instance. ..."
> >
> > Which value? submittedValue? or localValue? or "modelValue"?.
> >
> > In some point of time "required" was assumed as "not null" or "empty" but both
> > are not the same concept.
> >
> > The problematic line is this one in the javadoc of UIInput.validate() :
> >
> > "... Retrieve the submitted value with getSubmittedValue(). If this returns
> > null, exit without further processing. (This indicates that no value was
> > submitted for this component.) ..."
> >
> > I think that the case where "no value was submitted for this component" is
> > underspecified. "required" attribute is different to RequiredValidator, which
> > is really a NotEmptyValidador. What happens here is "required" property means
> > "submitted" and "not empty".
> >
> > regards,
> >
> > Leonardo Uribe
> >
> > 2016-12-01 3:27 GMT-05:00 Bauke Scholtz <balusc_at_gmail.com>:
> > Hi,
> >
> > Here's a related Stack Overflow post of mine on the subject: http://stackoverflow.com/q/17773979/157882
> >
> > Cheers, B
> >
> > On Thu, Dec 1, 2016 at 8:30 AM, Bauke Scholtz <balusc_at_gmail.com> wrote:
> > Hi,
> >
> > Yes, but this indicaties a bad model. The normal solution would be to put a @NotNull constraint on the entity or a NOT NULL constraint on the column.
> >
> > Cheers, B
> >
> >
> > On Wed, Nov 30, 2016, 23:33 Neil Griffin <neil.griffin_at_portletfaces.org> wrote:
> > Dear Friends of JSF,
> >
> > The problem is more general than the h:inputSecret validation example.
> >
> > Instead, consider this example:
> >
> > <h:inputText id="lastName" required="true"
> > value="#{backingBean.lastName}" />
> >
> > If <input type="text" name="lastName"/> is removed from the DOM prior to submitting the form (hack the postback such that the "lastName" request parameter is not present), then validation of the lastName value is bypassed and the UPDATE_MODEL_VALUES phase will be reached. This is invalid because the model will not contain a lastName value (even though the model requires it).
> >
> > To see this problem in action, follow the instructions on this page:
> > http://www.liferayfaces.org/web/guest/jsfspec1433
> >
> > The code that Ed is proposing that we fix (enabled by the proposed context-parameter) can be found here:
> > https://github.com/javaserverfaces/mojarra/blob/master/jsf-api/src/main/java/javax/faces/component/UIInput.java#L991-L993
> >
> > if (submittedValue == null) {
> > return;
> > }
> >
> > Q: Would it cause a backward compatibility problem if we simply made the following change?
> >
> > if ((submittedValue == null) && !isRequired()) {
> > return;
> > }
> >
> > In other words, is it necessary to introduce the context-param along with the fix?
> >
> > Thanks,
> >
> > Neil
> >
> > > On Nov 30, 2016, at 7:35 AM, Josh Juneau <juneau001_at_gmail.com> wrote:
> > >
> > > I think that the proposal looks fine, but I agree with Bauke's sentiments as this seems like a fairly non-standard use case.
> > >
> > > Josh Juneau
> > > juneau001_at_gmail.com
> > > http://jj-blogger.blogspot.com
> > > https://www.apress.com/index.php/author/author/view/id/1866
> > >
> > >
> > > On Wed, Nov 30, 2016 at 3:47 AM, arjan tijms <arjan.tijms_at_gmail.com> wrote:
> > > Hi,
> > >
> > > An "always run validator when required is true" seems okay to me. I did spot a small typo in the text, as it currently says:
> > >
> > > " If the value of "required" is false, the required attribute is not set not set"
> > >
> > > I assume the second "not set" should not be there.
> > >
> > > The example is indeed a little peculiar. I assume the user does this to avoid having a separate backing bean with an action method that only calls "request.authenticate", but becoming authenticated as a side-effect of running validation would probably not pass code review in a lot of places I think.
> > >
> > > Kind regards,
> > > Arjan Tijms
> > >
> > >
> > > On Wed, Nov 30, 2016 at 8:21 AM, Bauke Scholtz <balusc_at_gmail.com> wrote:
> > > Hi,
> > >
> > > Proposal itself looks good, but I can't think of any use case where it would be used as a real solution instead of as a workaround to a design problem. You?
> > >
> > > Cheers, B
> > >
> > > On Tue, Nov 29, 2016 at 6:15 PM, Edward Burns <edward.burns_at_oracle.com> wrote:
> > > Hello Volunteers,
> > >
> > > Neil Griffin brought this issue to my attention [1] and has been ardently
> > > advocating for it to be addressed in 2.3.
> > >
> > > When you say required="true" on a UIInput component, the validation
> > > must always take place, even when there is no entry in the request
> > > corresponding to that component.
> > >
> > > Background:
> > >
> > > Consider this login page:
> > >
> > > <h:inputText id="userName" required="true"
> > > value="#{backingBean.userName}" />
> > >
> > > <h:inputSecret id="password" required="true"
> > > validator="#{backingBean.validatePassword}"
> > > value="#{backingBean.password}" />
> > >
> > > <h:commandButton action="/views/authenticatedUser.xhtml" />
> > >
> > >
> > > If the postback is hacked such that the userName is present as a request
> > > parameter, but the password is not, the password validator would be
> > > bypassed. If the password validator is used as the entry point to
> > > perform authentication, this could cause problems.
> > >
> > > Now, it must be said that using a validator on a password field as the
> > > entry point to perform authentication is a particular design choice.
> > > This design choice runs a bit counter to the stated purpose of the
> > > validation system, which is to ensure syntactic and some level of
> > > semantic validity of fields. There are other ways to perform
> > > authentication that do not rely on the validation system for this
> > > purpose.
> > >
> > > Nonetheless, we would like to accomodate this use case.
> > >
> > > Proposal:
> > >
> > > For JSF 2.3, I propose the following.
> > >
> > > Modify PDF section 3.5.4 to read:
> > >
> > >
> > > Spec> *The render-independent property required is a shorthand for the
> > > Spec> function of a required validator. If the value of this property is
> > > Spec> true, **there is an entry in the request payload corresponding to
> > > Spec> this component**, and the component has no value, the component is
> > > Spec> marked invalid and a message is added to the FacesContext
> > > Spec> instance.*
> > >
> > >
> > > Modify the JavaDoc for UIInput.validate(). Modify the first bullet
> > > point to read:
> > >
> > >
> > > Spec> Retrieve the submitted value with getSubmittedValue(). If this
> > > Spec> returns null, and the
> > > Spec> javax.faces.component.UIInput.ALWAYS_PERFORM_VALIDATION_WHEN_REQUIRED_IS_TRUE
> > > Spec> context-parameter is set to true (ignoring case), examine the
> > > Spec> value of the "required" property. If the value of "required" is
> > > Spec> true, continue as below. If the value of "required" is false, the
> > > Spec> "required" attribute is not set not set, exit without further
> > > Spec> processing. If the context-paramater is not set, or is set to
> > > Spec> false (ignoring case) exit without further processing. (This
> > > Spec> indicates that no value was submitted for this component.)
> > >
> > >
> > > With these changes, the javadoc for UIInput.validateValue() can remain
> > > unchanged.
> > >
> > > ACTION: Please let us know your thoughts about this by COB 2016-12-06.
> > > I really hope you all can accept it as is, but I think the chance for EG
> > > discussion is warranted here.
> > >
> > > Ed
> > >
> > > --
> > > | edward.burns_at_oracle.com | office: +1 407 458 0017
> > >
> > > [1] https://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-1433
> > >
> > >
> > >
> >
> >
> >
>
>