Validator skipped when input is removed in client – is this as per JSF specification?

依然范特西╮ 提交于 2019-12-17 16:22:39

问题


I have a page with an input text component marked as required="true" and having a custom Validator in server side.

Now as a client, I submit the page without the HTML element rendered by that component (this can be easily achieved by removing the element from the DOM tree using browser's builtin DOM element inspector). The form is successfully submitted, without the server side validation of this required component.

Is this as per JSF specification? Is there a way to specify that the validators in the page are to be executed even if the posted page do not contain them?


回答1:


This is indeed as per the specification. Here's an extract of relevance from UIInput#validate() javadoc (emphasis mine):

Retrieve the submitted value with getSubmittedValue(). If this returns null, and the value of the ALWAYS_PERFORM_VALIDATION_WHEN_REQUIRED_IS_TRUE context-param is true (ignoring case), examine the value of the "required" property. If the value of "required" is true, continue as below. If the value of "required" is false or the required attribute is not set, exit without further processing. If the context-param is not set, or is set to false (ignoring case), exit without further processing. (This indicates that no value was submitted for this component.)

An empty input will send an empty string, not null. A complete absence of the input will send null, not empty string.

You can thus disable the observed behavior by adding the following context parameter:

<context-param>
    <param-name>javax.faces.ALWAYS_PERFORM_VALIDATION_WHEN_REQUIRED_IS_TRUE</param-name>
    <param-value>true</param-value>
</context-param>

Note that this context parameter is new since JSF 2.3 and backported into Mojarra 2.2.16, 2.1.29-10 and 1.2_15-06. It is not supported in older versions. See also JSFSPEC-1433 and the expert group discussion about this issue.

Whether that is harmful or not depends on the business logic. A decently designed model (business logic and/or data model) which doesn't consider null as expected case would cause a null pointer exception elsewhere, or a SQL constraint violation (NOT NULL), which will usually end up in a HTTP 500 error response. But if the model actually considers null as an expected case, then it's likely a fault in the model. The view (the JSF page), intented to merely present the model, can then do little against it.

If the business logic or data model can really not be altered to consider null as an exceptional case (i.e. never assume/accept the given value as null), and you happen to use JPA, then your best bet is to add a @NotNull on the property. Whilst JSF will bypass validation on it, JPA will still validate it, causing still an exception and a HTTP 500 error. I'd in this case only wonder why the DB column doesn't have a NOT NULL constraint in first place. Alternatively, do class level validation.

Noted should be that MyFaces logs a warning like below on this:

Mar 16, 2016 8:55:52 AM org.apache.myfaces.shared.renderkit.html.HtmlRendererUtils decodeUIInput
WARNING: There should always be a submitted value for an input if it is rendered, its form is submitted, and it was not originally rendered disabled or read-only. You cannot submit a form after disabling an input element via javascript. Consider setting read-only to true instead or resetting the disabled value back to false prior to form submission.
Component : {Component-Path : [Class: javax.faces.component.UIViewRoot,ViewId: /test.xhtml][Class: javax.faces.component.html.HtmlBody,Id: j_id_5][Class: javax.faces.component.html.HtmlForm,Id: j_id_6][Class: javax.faces.component.html.HtmlInputText,Id: j_id_7] Location: /test.xhtml at line 22 and column 33}



来源:https://stackoverflow.com/questions/17773979/validator-skipped-when-input-is-removed-in-client-is-this-as-per-jsf-specifica

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!