7

我有一个页面,其中输入文本组件标记为required="true"并在服务器端具有自定义Validator

现在作为客户端,我提交的页面没有由该组件呈现的 HTML 元素(这可以通过使用浏览器的内置 DOM 元素检查器从 DOM 树中删除元素来轻松实现)。表单已成功提交,而无需对该必需组件进行服务器端验证。

这是按照 JSF 规范吗?有没有办法指定页面中的验证器即使发布的页面不包含它们也要执行?

4

1 回答 1

7

这确实符合规范。UIInput#validate()以下是javadoc的相关摘录(重点是我的):

使用 检索提交的值getSubmittedValue()。如果返回null,并且ALWAYS_PERFORM_VALIDATION_WHEN_REQUIRED_IS_TRUEcontext-param 的值为真(忽略大小写),请检查“必需”属性的值。如果“required”的值为真,则继续如下。如果“required”的值为false或未设置required属性,则不做进一步处理直接退出。如果 context-param 未设置,或者设置为 false(忽略大小写),则退出而不进行进一步处理。(这表示没有为此组件提交任何值。)

空输入将发送一个空字符串,而不是null. 完全没有输入将发送null,而不是空字符串。

因此,您可以通过添加以下上下文参数来禁用观察到的行为:

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

请注意,此上下文参数是自 JSF 2.3 以来的新参数,并已向后移植到 Mojarra 2.2.16、2.1.29-10 和 1.2_15-06。旧版本不支持它。另请参阅JSFSPEC-1433专家组对此问题的讨论

这是否有害取决于业务逻辑。一个设计得体的模型(业务逻辑和/或数据模型)不考虑null预期的情况会导致其他地方出现空指针异常,或者违反 SQL 约束 ( NOT NULL),这通常会导致 HTTP 500 错误响应。但是,如果模型实际上将null其视为预期情况,那么它很可能是模型中的错误。视图(JSF 页面)仅用于呈现模型,因此对它几乎无能为力。

如果业务逻辑或数据模型确实不能被更改null为例外情况(即从不假定/接受给定值null),并且您碰巧使用 JPA,那么最好的选择是@NotNull在属性上添加 a。虽然 JSF 会绕过验证,但 JPA 仍会验证它,仍然会导致异常和 HTTP 500 错误。在这种情况下,我只想知道为什么 DB 列首先没有NOT NULL约束。或者,进行类级别验证

应该注意的是 MyFaces 会在此记录如下警告:

2016 年 3 月 16 日上午 8 点 55 分 52 秒 org.apache.myfaces.shared.renderkit.html.HtmlRendererUtils decodeUIInput
警告:如果它被渲染,它的表单被提交,它应该总是有一个提交的值,它不是最初呈现为禁用或只读。通过 javascript 禁用输入元素后,您无法提交表单。考虑将只读设置为 true,或者在提交表单之前将禁用的值重置为 false。
组件:{组件路径:[类:javax.faces.component.UIViewRoot,ViewId:/test.xhtml][类:javax.faces.component.html.HtmlBody,Id:j_id_5][类:javax.faces.component .html.HtmlForm,Id: j_id_6][Class: javax.faces.component.html.HtmlInputText,Id: j_id_7] 位置:/test.xhtml 第 22 行第 33 列}

于 2015-08-24T10:39:00.473 回答