validation - 在 PrimeFaces 的文件上传监听器中验证上传图像的尺寸

标签 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))那么 <p:commandButton> 的 Action 监听器被评估为 true (上面的 insert() 方法)不应该被调用,但是它被调用了,并且这种验证意味着根本没有效果。

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

我在这里做错了什么?如何验证上传图片的尺寸?

最佳答案

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

这确实有些尴尬。作为<p:fileUpload mode="advanced">不支持Validator正如您已经发现的那样,这个问题并没有真正干净的解决方案。您应该摆弄 View 作用域 bean 属性,以维护同一 View 上请求之间的验证状态。

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 。最终用户能够自行修复所有问题。

关于validation - 在 PrimeFaces 的文件上传监听器中验证上传图像的尺寸,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22659268/

相关文章:

jQuery 验证 : function when specific element is valid

Google 表单/Google 表格的 JavaScript 验证

javascript - Jsf 命令按钮调用 javascript 函数然后刷新整个页面

jsf - PrimeFaces Tree 组件,从托管 bean 设置选定节点

ruby-on-rails - 带有 Paperclip 的文件类型的自定义缩略图

javascript - 有没有办法在 Keystone JS 上上传视频?

python - 使用 Python 验证电子邮件地址

validation - Grails 验证不起作用

jsf - PrimeFaces commandButton actionListener 未触发

python - 我是否正确解析了这个 HTTP POST 请求?