简体   繁体   English

PrimeFaces<p:fileUpload mode="advanced"> 验证器没有被解雇

[英]PrimeFaces <p:fileUpload mode="advanced"> validator not fired

since fileLimit doesn't exist in primefaces 3.4 anymore I'm trying a work around implementing a validator, the problem is that the method validate is never invoked.由于fileLimit 不再存在于primefaces 3.4 中,我正在尝试解决实现验证器的问题,问题是从未调用过validate 方法。 That's my Validator:那是我的验证器:

@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");
            }
        }
    }
}

and in my facelet I've tried:在我的 facelet 中,我尝试过:

    <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>

and:和:

    <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>

and:和:

    <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>

and:和:

    <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>

but the validate method is never called.但从未调用过验证方法。 What is the correct way to do it?正确的做法是什么?

According to the FileUpload and FileUploadRenderer source code, the validator is only invoked when mode="simple" is been used (note: this in turn requires ajax="false" on command).根据FileUploadFileUploadRenderer源代码,只有在使用mode="simple"时才会调用验证器(注意:这反过来需要ajax="false"命令)。 The advanced mode will namely not set the uploaded file as component's submitted value, causing it to remain null until the listener method is invoked.高级模式不会将上传的文件设置为组件的提交值,导致它保持null直到调用侦听器方法。 As long as the submitted value is null , the validators are not invoked.只要提交的值为null ,就不会调用验证器。

I'm not sure if this is intentional.我不确定这是否是故意的。 Theoretically, it should be possible to set UploadedFile as submitted value and have the validator to rely on it.从理论上讲,应该可以将UploadedFile设置为提交值并让验证器依赖它。 You might want to create an enhancement report at PrimeFaces issue tracker .您可能希望在PrimeFaces 问题跟踪器上创建增强报告。

In the meanwhile, in spite of it being a poor practice , your best bet is really performing the validation in fileUploadListener method.同时,尽管这是一个糟糕的做法,但最好的办法是在fileUploadListener方法中真正执行验证。 You can just trigger validation failure add faces messages through the FacesContext like follows:您可以通过FacesContext触发验证失败添加人脸消息,如下所示:

if (fail) {
    context.validationFailed();
    context.addMessage(event.getComponent().getClientId(context), new FacesMessage(
        FacesMessage.SEVERITY_ERROR, messageSummary, messageDetail));
}

Otherwise, you'd need to create a custom renderer for the <p:fileUpload> which sets the submitted value during the decode() (I however don't guarantee that it would work in practice, you'll maybe stumble upon a peculiar problem which may turn out to be the reason why PrimeFaces didn't initially implement it like that).否则,您需要为<p:fileUpload>创建一个自定义渲染器,它在decode()期间设置提交的值(但我不保证它会在实践中起作用,您可能会偶然发现一个特殊的问题,这可能是 PrimeFaces 最初没有像那样实现它的原因)。

By the way, your first and second validator attempt are correct.顺便说一句,您的第一次和第二次验证器尝试是正确的。 The third attempt works only if you used @ManagedBean instead of @FacesValidator ( which is often done when injection of an @EJB is mandatory — which isn't possible in a @FacesValidator ).第三次尝试仅在您使用@ManagedBean而不是@FacesValidator当必须注入@EJB时通常会这样做——这在@FacesValidator中是@FacesValidator )。 The fourth attempt is invalid.第四次尝试无效。

For validating a required primefaces file upload in mode advanced (ajax) it is possible to use this:为了在高级模式(ajax)中验证所需的primefaces文件上传,可以使用:

<f:metadata>
    <f:event listener="#{bean.processValidations()}" type="postValidate" />
</f:metadata>

Where the implementation of the bean.processValidations() method would be something along the lines of: 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();
        }
    }

Where fileUploadsBean would be a REQUEST scoped CDI bean (won't work with standard JSF ManagedBeans) which you inject to your bean which has the processValidations() method defined, the method fileUploadsBean.getFileUploadComponent() returns the primefaces file upload component (you will use <p:fileUpload binding="#{fileUploadsBean.fileUploadComponent}" ...> for that). fileUploadsBean将是一个 REQUEST 范围的 CDI bean(不适用于标准 JSF ManagedBeans),您将它注入到您的 bean 中,该 bean 定义了 processValidations processValidations()方法,方法fileUploadsBean.getFileUploadComponent()返回 primefaces 文件上传组件(您将使用<p:fileUpload binding="#{fileUploadsBean.fileUploadComponent}" ...>为此)。 The method isFileUploaded() will determine if the file has been uploaded or not (probably just a null check on a member variable which you fill from fileUploadListener).方法isFileUploaded()将确定文件是否已上传(可能只是对从 fileUploadListener 填充的成员变量进行空检查)。

If you want to highlight the file upload button you can of course conditionally add a styleClass which you can then use for adding a red border for example.如果您想突出显示文件上传按钮,您当然可以有条件地添加一个 styleClass,然后您可以使用它来添加红色边框。

styleClass="#{fileUploadsBean.fileUploadComponent.valid ? '' : 'validationFailed'}"

As a result the validation failed message for the primefaces file upload will be displayed along with all other jsf validation messages.因此,primefaces 文件上传的验证失败消息将与所有其他 jsf 验证消息一起显示。 You might have problem with maintaining order of the validation messages (will be always at the end), but it still beats displaying the failed upload file validation after user dealt with all the standard jsf validation messages from different fields and your action in a backing bean has been finally reached.您可能在维护验证消息的顺序时遇到问题(将始终在最后),但在用户处理来自不同字段的所有标准 jsf 验证消息以及您在支持 bean 中的操作后,它仍然胜过显示失败的上传文件验证终于达到了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM