因为在primefaces 3.4中不存在fileLimit我正在尝试实现验证器,问题是从不调用方法validate。那是我的验证员:
@FacesValidator(value ="fileLimitValidator")
public class FileLimitValidator implements Validator {
@Override
public void validate(final FacesContext context, final UIComponent component,
final Object value) throws ValidatorException {
final String fileLimit = (String)component.getAttributes().get("fileLimit");
final String size = (String)component.getAttributes().get("size");
if (fileLimit!=null && size!=null) {
if (Integer.valueOf(size) >= Integer.valueOf(fileLimit)) {
FacesUtils.throwErrorExceptionFromComponent(component,"fichero_confidencialidad_error");
}
}
}
}
在我的脸上我试过了:
<p:fileUpload id="#{id}FileUpload"
fileUploadListener="#{bean[metodoTratarFichero]}" mode="advanced"
multiple="true" allowTypes="#{allowTypes}" showButtons="false"
update="#{id}ListaDocs #{id}MsgError" auto="true"
label="#{fileuploadmsg.label_boton}"
invalidFileMessage="#{fileuploadmsg.tipo_incorrecto}" >
<f:validator validatorId="fileLimitValidator"/>
<f:attribute name="fileLimit" value="#{fileLimit}"/>
<f:attribute name="size" value="#{listaDocumentos.size}"/>
</p:fileUpload>
和
<p:fileUpload id="#{id}FileUpload"
fileUploadListener="#{bean[metodoTratarFichero]}" mode="advanced"
multiple="true" allowTypes="#{allowTypes}" showButtons="false"
update="#{id}ListaDocs #{id}MsgError" auto="true"
label="#{fileuploadmsg.label_boton}"
invalidFileMessage="#{fileuploadmsg.tipo_incorrecto}"
validator="fileLimitValidator">
<f:attribute name="fileLimit" value="#{fileLimit}"/>
<f:attribute name="size" value="#{listaDocumentos.size}"/>
</p:fileUpload>
和
<p:fileUpload id="#{id}FileUpload"
fileUploadListener="#{bean[metodoTratarFichero]}" mode="advanced"
multiple="true" allowTypes="#{allowTypes}" showButtons="false"
update="#{id}ListaDocs #{id}MsgError" auto="true"
label="#{fileuploadmsg.label_boton}"
invalidFileMessage="#{fileuploadmsg.tipo_incorrecto}"
validator="#{fileLimitValidator}">
<f:attribute name="fileLimit" value="#{fileLimit}"/>
<f:attribute name="size" value="#{listaDocumentos.size}"/>
</p:fileUpload>
和
<p:fileUpload id="#{id}FileUpload"
fileUploadListener="#{bean[metodoTratarFichero]}" mode="advanced"
multiple="true" allowTypes="#{allowTypes}" showButtons="false"
update="#{id}ListaDocs #{id}MsgError" auto="true"
label="#{fileuploadmsg.label_boton}"
invalidFileMessage="#{fileuploadmsg.tipo_incorrecto}"
validator="#{fileLimitValidator.validate}">
<f:attribute name="fileLimit" value="#{fileLimit}"/>
<f:attribute name="size" value="#{listaDocumentos.size}"/>
</p:fileUpload>
但从不调用validate方法。这样做的正确方法是什么?
答案 0 :(得分:15)
根据FileUpload
和FileUploadRenderer
源代码,仅在使用mode="simple"
时调用验证器(注意:这反过来需要ajax="false"
命令)。高级模式将不会将上载的文件设置为组件的提交值,从而使其保持null
,直到调用侦听器方法。只要提交的值为null
,就不会调用验证程序。
我不确定这是否是故意的。从理论上讲,应该可以将UploadedFile
设置为提交的值,并让验证器依赖它。您可能希望在PrimeFaces issue tracker创建增强报告。
与此同时,尽管它是poor practice,但您最好的选择是在fileUploadListener
方法中进行验证。您只需通过FacesContext
触发验证失败添加面部消息,如下所示:
if (fail) {
context.validationFailed();
context.addMessage(event.getComponent().getClientId(context), new FacesMessage(
FacesMessage.SEVERITY_ERROR, messageSummary, messageDetail));
}
否则,您需要为<p:fileUpload>
创建一个自定义渲染器,在decode()
期间设置提交的值(但我不保证它会在实践中起作用,你会也许偶然发现一个奇怪的问题,这可能是PrimeFaces最初没有像那样实现它的原因。)
顺便说一句,您的第一次和第二次验证器尝试都是正确的。第三次尝试仅在您使用@ManagedBean
而非@FacesValidator
(which is often done when injection of an @EJB
is mandatory — which isn't possible in a @FacesValidator
)时才有效。第四次尝试无效。
答案 1 :(得分:1)
为了在模式高级(ajax)中验证所需的primefaces文件上传,可以使用它:
<f:metadata>
<f:event listener="#{bean.processValidations()}" type="postValidate" />
</f:metadata>
bean.processValidations()
方法的实现方式如下:
public void processValidations() {
FacesContext context = FacesContext.getCurrentInstance();
UIInput fileUploadComponent = fileUploadsBean.getFileUploadComponent();
if (fileUploadComponent!=null && !isFileUploaded()) {
fileUploadComponent.setValid(false);
context.addMessage(fileUploadComponent.getClientId(context), new FacesMessage(FacesMessage.SEVERITY_ERROR, messageSummary, messageDetail));
context.validationFailed();
}
}
其中fileUploadsBean
是一个REQUEST作用域的CDI bean(不会使用标准的JSF ManagedBeans),你注入了定义了processValidations()
方法的bean,方法{{1返回primefaces文件上传组件(您将使用fileUploadsBean.getFileUploadComponent()
)。方法<p:fileUpload binding="#{fileUploadsBean.fileUploadComponent}" ...>
将确定文件是否已上载(可能只是对从fileUploadListener填充的成员变量进行空检查)。
如果您想突出显示文件上传按钮,您当然可以有条件地添加一个styleClass,然后您可以使用它来添加红色边框。
isFileUploaded()
因此,将显示primefaces文件上载的验证失败消息以及所有其他jsf验证消息。您可能在维护验证消息的顺序方面遇到问题(将始终在最后),但在用户处理来自不同字段的所有标准jsf验证消息以及您在辅助bean中的操作后,它仍然会显示失败的上载文件验证终于到了。