我有一个 JSF 2.0应用程序,它也使用 Primefaces 3.3 。目前有一个很好的功能,如果相关的<p:inputText>
使用required="true"
属性,标签将用星号装饰。
此字段绑定到bean属性,该属性使用@NotNull
验证约束进行注释。当bean属性已经使用@NotNull注释时,在XHTML中添加required="true"
似乎是多余的并且容易出错。
是否有钩子或某种方法来自动装饰与@NotNull绑定到属性的组件的标签?
非常感谢任何想法或建议。
答案 0 :(得分:3)
注意:这是一个黑客攻击。由于它使用了内省,它可能会对性能产生影响
在基本级别,如果字段使用@NotNull
注释,您需要知道的内容。对于视图范围的bean,在@PostConstruct
这样的合理位置执行此检查。声明一个全局变量以确定所需的属性
boolean requiredAttribute;
@PostConstruct
public void init{
Field theField = this.getClass().getField("theField");
NotNull theAnnotation = theField.getAnnotation(NotNull.class);
if(theAnnotation != null){
requiredAttribute = true;
}
}
将required
属性绑定到辅助bean中的变量
<p:inputText id="inputit" required="#{myBean.requiredAttribute}"/>
答案 1 :(得分:3)
此解决方案基于PF 6.0,我不记得先前版本中是否有BeanValidationMetadataExtractor
。无论如何,创建一个DIY提取器是一项简单的任务。
我有类似的问题。在我的具体案例中:
UIInput
)required="true"
,因为它已经绑定到@NotNull
/ @NotBlank
属性/字段所以,这就是我所做的:
import java.util.Set;
import javax.el.ValueExpression;
import javax.faces.component.UIInput;
import javax.faces.context.FacesContext;
import javax.faces.event.AbortProcessingException;
import javax.faces.event.PreRenderComponentEvent;
import javax.faces.event.SystemEvent;
import javax.faces.event.SystemEventListener;
import javax.validation.constraints.NotNull;
import javax.validation.metadata.ConstraintDescriptor;
import org.hibernate.validator.constraints.NotBlank;
import org.hibernate.validator.constraints.NotEmpty;
import org.omnifaces.util.Faces;
import org.primefaces.context.RequestContext;
import org.primefaces.metadata.BeanValidationMetadataExtractor;
public class InputValidatorConstraintListener implements SystemEventListener
{
@Override
public boolean isListenerForSource(Object source)
{
return source instanceof UIInput;
}
@Override
public void processEvent(SystemEvent event) throws AbortProcessingException
{
if(event instanceof PreRenderComponentEvent)
{
UIInput component = (UIInput) event.getSource();
component.getPassThroughAttributes().computeIfAbsent("data-required", k ->
{
ValueExpression requiredExpression = component.getValueExpression("required");
if(requiredExpression != null || !component.isRequired())
{
FacesContext context = Faces.getContext();
ValueExpression valueExpression = component.getValueExpression("value");
RequestContext requestContext = RequestContext.getCurrentInstance();
try
{
Set<ConstraintDescriptor<?>> constraints = BeanValidationMetadataExtractor.extractAllConstraintDescriptors(context, requestContext, valueExpression);
if(constraints != null && !constraints.isEmpty())
{
return constraints.stream()
.map(ConstraintDescriptor::getAnnotation)
.anyMatch(x -> x instanceof NotNull || x instanceof NotBlank || x instanceof NotEmpty);
}
}
catch(Exception e)
{
return false;
}
}
return false;
});
}
}
}
并在faces-config.xml中声明它:
<?xml version="1.0" encoding="utf-8"?>
<faces-config version="2.2" xmlns="http://xmlns.jcp.org/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee http://xmlns.jcp.org/xml/ns/javaee/web-facesconfig_2_2.xsd">
<application>
<system-event-listener>
<system-event-listener-class>it.shape.core.jsf.listener.InputValidatorConstraintListener</system-event-listener-class>
<system-event-class>javax.faces.event.PreRenderComponentEvent</system-event-class>
</system-event-listener>
</application>
</faces-config>
通过此侦听器UIInput
使用data-required
passthrough属性进行渲染:
<input
id="form:editPanelMain:j_idt253"
name="form:editPanelMain:j_idt253"
type="text"
value="Rack Assemply"
size="80"
data-required="true" <============================ NOTE THIS!!
data-widget="widget_form_editPanelMain_j_idt253"
class="ui-inputfield ui-inputtext ui-widget ui-state-default ui-corner-all"
role="textbox"
aria-disabled="false"
aria-readonly="false">
现在,我使用css规则来突出显示这些字段:
input[data-required='true'],
.ui-inputfield[data-required='true'],
*[data-required='true'] .ui-inputfield {
box-shadow: inset 0px 2px 2px #bf8f8f;
}
您可以调整此侦听器,以根据需要设置组件,或使用另一种方法满足您的特定需求。
另一种方法可能是:
UILabel
而不是UIInput
s UIInput
/ for
标签的ValueExpression相关联的forValue
UIInput
验证限制UIInput.setRequired(true)
性能影响可以忽略不计,因为我测试了大约3000个组件的复杂页面。