<h:inputFile> 的客户端验证

Client-side validation on <h:inputFile>

我的 JSF 视图使用普通 <h:inputFile> 上传文件。它有一个 AJAX 动作,可以在选择文件后立即开始上传(onchange 事件)。我想在客户端使用 HTML5 DOM File API 和 Java 脚本对文件进行一些基本验证,以 在某些情况下停止上传 .

(是的,我明白 Java 可以绕过这个检查的脚本,这只是一个 "bandwidth and time saving check" 对于不小心选择了错误文件的普通用户 - 仍然会有服务器 -侧面验证。而且我还了解到文件 API 可能尚未在所有(较旧的)浏览器上可用。)

简化的 JSF 文件:

<html
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:f="http://java.sun.com/jsf/core"
>
<h:head>
    <h:outputScript target="body">
//<![CDATA[
function doUpload(data, event) {
    if ("event" == data.type) {
        switch (data.status) {
            case "begin":
                // validate file size
                if (data.source.files[0].size > 20971520) { //20MiB
                    alert('ERROR: File too big!');
                    event.preventDefault();
                    return false;
                }
                // TODO show throbber
                break;

            case "complete":
                // TODO hide throbber
                break;

            case "success":
                break;
        }
    }
}
//]]>
    </h:outputScript>
</h:head>
<h:body>
    <h:form id="testuploadform" enctype="multipart/form-data">
        <h:inputFile id="uploadFile" name="uploadFile" value="#{testBean.uploadFile}">
            <!--  TODO validator/s for server-side validation -->
            <f:ajax event="change" listener="#{testBean.ajaxLst_autoUpload}"
                    onevent="function(data){ doUpload(data,event); }"
            />
        </h:inputFile>
    </h:form>
</h:body>
</html>

似乎尽管使用了 event.preventDefault() 调用,但事件仍得到进一步处理:文件已上传,我的侦听器函数 TestBean.ajaxLst_autoUpload() 能够获取它并对其进行处理。

我想做的事情有可能吗?我该怎么做?

====

我想另一种方法是 use the XMLHttpRequest.open() process to issue a request from AJAX(仅在验证成功后),但是我不确定如何执行 "valid" POST 请求 到 JSF - 我只看到了 PHP 和 Java Servlet 的示例。我主要不热衷于编写上传 Servlet(尽管如果需要可以完成,并且可以通过 google 搜索示例),而且我不太了解幕后的 JSF,不知道它如何与 Servlet 对应。但是在这方面的任何指示也将不胜感激。

<f:ajax onevent> 中的处理为时已晚。请改用输入组件的 onchange 属性。基本上:

<h:inputFile ... onchange="return validate(this)">