在PrimeFaces中验证文件上载侦听器中上载图像的尺寸

时间:2014-03-26 11:15:45

标签: validation jsf file-upload primefaces jsf-2.2

我正在使用<p:fileUpload>上传图片,如下所示。

<p:outputLabel for="txtCatImage" value="#{messages['category.image']}"/>

<p:fileUpload id="txtCatImage" mode="advanced" 
              dragDropSupport="true" required="true"
              sizeLimit="1000000" fileLimit="1" multiple="false" 
              cancelLabel="#{messages['fileupolad.cancelLabel']}"
              label="#{messages['fileupolad.label']}"
              uploadLabel="#{messages['fileupolad.uploadLabel']}" 
              allowTypes="/(\.|\/)(gif|jpe?g|png)$/"
              invalidFileMessage="#{messages['fileupolad.invalidFileMessage']}"
              invalidSizeMessage="#{messages['fileupolad.invalidSizeMessage']}"
              fileLimitMessage="#{messages['fileupolad.fileLimitMessage']}"
              fileUploadListener="#{categoryManagedBean.fileUploadListener}"/>
<p:message for="txtCatImage" showSummary="false"/>

<p:commandButton id="btnSubmit" update="panel messages"
                 actionListener="#{categoryManagedBean.insert}"
                 value="#{messages['button.save']}"/>
装饰有fileUploadListener的相应托管bean中的

@ViewScoped如下所示。

//This is just a utility method and can be placed anywhere in the application.
private static boolean validateImageDimensions(byte[] bytes) throws IOException {
    BufferedImage bufferedImage = ImageIO.read(new ByteArrayInputStream(bytes));        
    return bufferedImage.getHeight()>=750 || bufferedImage.getWidth()>=650;
}

public void fileUploadListener(FileUploadEvent event) throws IOException {
    UploadedFile uploadedFile = event.getFile();
    byte[] bytes = IOUtils.toByteArray(uploadedFile.getInputstream());

    if(!Utility.validateImageDimensions(bytes)) {
        FacesContext context = FacesContext.getCurrentInstance();
        context.validationFailed();
        FacesMessage message = new FacesMessage(FacesMessage.SEVERITY_FATAL, "Message summary", "Error message");
        FacesContext.getCurrentInstance().addMessage(event.getComponent().getClientId(context), message);
    }
    else {//Do something.}
}

<p:commandButton>的监听器如下所示,如果fileUploadListener()中的验证失败,则将被调用。

public void insert() {
    //Code to invoke an EJB to insert a new row along with the uploaded file.
}

如果将if(!Utility.validateImageDimensions(bytes))评估为true,那么<p:commandButton>的动作监听器(上面的insert()方法)应该,但会调用它并且这种验证意味着没有任何影响。

As already stated,PrimeFaces文件上传验证程序不起作用。

我在这里做错了什么?验证上传图片尺寸的方法是什么?

1 个答案:

答案 0 :(得分:2)

导致您的具体问题是因为上传操作发生在与保存操作不同的HTTP请求中。您首先选择了该文件,然后按上传(请求#1),然后按保存按钮(请求#2),对吗?浏览器的内置开发人员工具集中的网络监视器(按F12)也应该确认它。 FacesContext#validationFailed()本质上是请求作用域,就像FacesContext本身一样。因此,当您在调用上传操作的请求期间设置它时,它只是&#34;重置&#34;在请求中调用保存操作。

这确实有点尴尬。由于<p:fileUpload mode="advanced">并不支持Validator,正如您已经发现的那样,这个问题并不是一个干净的解决方案。您应该摆弄视图范围的bean属性,以维护同一视图上的请求的验证状态。

private boolean validationFailed;

public void fileUploadListener(FileUploadEvent event) throws IOException {
    // ...
    validationFailed = !Utility.validateImageDimensions(bytes);

    if (validationFailed) {
        // Add message.
    }
    else {
        // Process upload.
    }
}

public void insert() {
    if (validationFailed) {
        // Add message.
    }
    else {
        // Process insert.
    }
}

顺便说一句,我不想​​将这些邮件设置为FATAL,而是设置为ERROR。最终用户即可自行固定它。