我在评估包含由其他标签创建的var
的EL表达式时遇到问题。
我有一个项目,我正在使用自定义验证器。
public class MyValidator implements Validator, StateHolder
我有一个与之关联的标记类:
public class MyValidatorTag extends ValidatorTag
此类允许属性fieldName
,并为标记添加适当的tld
文件:
<tag>
<name>my-validator</name>
<tag-class>my.packaga.MyValidatorTag</tag-class>
<body-content>JSP</body-content>
<description>This is my validator</description>
<attribute>
<name>fieldName</name>
<required>true</required>
<rtexprvalue>true</rtexprvalue>
<type>java.lang.String</type>
<description>This is some field I need</description>
</attribute>
</tag>
到目前为止一切顺利。但是这种设置不允许人们使用JSF EL表达式来表示属性值。 所以验证器类(不是标签类)我使用此代码来评估属性值:
public static String evaluateEl(String expression) {
String value = null;
if (expression == null) {
return "";
}
if ((expression.indexOf("#{") != -1)
&& (expression.indexOf("#{") < expression.indexOf('}'))) {
Object evaledValue =
FacesContext.getCurrentInstance().getApplication().createValueBinding(
expression).getValue(FacesContext.getCurrentInstance());
if (evaledValue != null) {
value = evaledValue.toString();
} else {
value = null;
}
} else {
value = expression;
}
return value;
}
它仅限于字符串,适用于大多数EL表达式。表达式Hello #{1 eq 2}
将使该属性具有值Hello false
。
但是有一种情况不适用。包含由另一个标记创建的var
的任何表达式都不起作用。数据表,数据系统,尤其是<f:loadBundle>
,例如
<f:loadBundle basename="mypackage.message.ui-strings" var="msgs" />
后跟包含验证器的输入组件:
<cust:my-validator fieldName="#{msgs['myfield1.name']}"></cust:my-validator>
Fieldname使用上面的表达式评估代码计算为空字符串。将其更改为#{requestScope.msgs....
并不能解决问题。查看loadBundle实现,它将var msgs
添加到请求范围,因此我不明白为什么vars对我不起作用。拜托,有人帮我理解。
答案 0 :(得分:4)
任何包含由另一个标记创建的var的表达式都不起作用。数据表,数据系统,最值得注意的是,例如
标记处理程序,例如<f:xxx>
,<c:xxx>
和一些<ui:xxx>
(那些不具有rendered
属性)在JSF视图构建时执行,何时生成JSF UI组件树。它们不是UI组件树的一部分。他们已经完成了生成必要的JSF UI组件的工作。
像<h:xxx>
和一些<ui:xxx>
(具有rendered
属性的那些)的UI组件在JSF视图渲染时执行,此时要生成要发送的大型HTML字符串到当前HTTP请求的HTTP响应。
因此他们不会同步运行。
验证者的最终用户有几种方法可以解决这个问题,所有这些都列在这个答案中:How to set converter properties for each row of a datatable?
对于开发人员,还有另一种解决方案,让验证程序扩展UIComponentBase
,然后在processValidators()
中执行作业。父组件仅由UIComponent#getParent()
提供,其提交的值可由UIInput#getSubmittedValue()
提供。