You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Primefaces 6.2迁移至7.0时文件上传类型验证报错求助

Primefaces 7.0 文件上传组件allowTypes验证报错解决方案

问题背景

从Primefaces 6.2迁移至7.0版本后,文件上传组件使用allowTypes="/(\.|\/)(pdf)$/"正则表达式限制PDF文件上传时,出现以下报错:

07-Nov-2023 10:28:39.858 WARNING [http-nio-8080-exec-3] org.primefaces.util.FileUploadUtils.isValidType The type of the uploaded file attachmentExample.pdf could not be validated
    javax.script.ScriptException: java.lang.NullPointerException: JavaScript ScriptEngine not available via the context ClassLoader or the extension ClassLoader.
        at org.primefaces.util.FileUploadUtils.isValidFileName(FileUploadUtils.java:177)
        at org.primefaces.util.FileUploadUtils.isValidType(FileUploadUtils.java:145)
        at org.primefaces.component.fileupload.NativeFileUploadDecoder.isValidFile(NativeFileUploadDecoder.java:118)
        at org.primefaces.component.fileupload.NativeFileUploadDecoder.decodeAdvanced(NativeFileUploadDecoder.java:111)
        at org.primefaces.component.fileupload.NativeFileUploadDecoder.decode(NativeFileUploadDecoder.java:56)
        at org.primefaces.component.fileupload.FileUploadRenderer.decode(FileUploadRenderer.java:60)
        at javax.faces.component.UIComponentBase.decode(UIComponentBase.java:832)
        at javax.faces.component.UIInput.decode(UIInput.java:773)

删除allowTypes参数后报错消失,但需保留PDF文件类型验证功能。

解决方案

方案1:改用非正则格式的allowTypes

Primefaces 7.0支持直接使用逗号分隔的文件扩展名或MIME类型作为allowTypes的值,无需依赖JavaScript引擎。修改组件参数:

<p:fileUpload id="fileupload"
              label="#{msg['page.application-decisions.selectFile']}"
              value="#{decisionBean.uploadedFile}"
              style="display: flex; "
              styleClass="button like-link font-14 -margin-bottom-20"
              mode="advanced"
              multiple="false"
              auto="true"
              dragDropSupport="false"
              allowTypes="application/pdf,.pdf"
              sizeLimit="10000000"
              invalidSizeMessage="#{msg['page.application-decisions.invalidSizeMessage']}"
              invalidFileMessage="#{msg['page.application-decisions.invalidFileMessage']}"
              fileLimitMessage="#{msg['page.application-decisions.fileLimitMessage']}"
              fileUploadListener="#{decisionBean.handleFileUpload}"
              disabled="#{decisionBean.application.anyDecisionNotNotified==true}"
              update="filemsg fileupload uploadedFileName @this">
</p:fileUpload>

这种方式会直接匹配文件的扩展名和MIME类型,避免正则解析引发的JS引擎问题。

方案2:添加JavaScript引擎依赖(若需保留正则写法)

如果必须使用正则表达式格式的allowTypes,需确保运行环境提供可用的JavaScript引擎:

  • 对于Java 11及以上版本,Nashorn引擎已被移除,需手动添加Maven依赖:
<dependency>
    <groupId>org.openjdk.nashorn</groupId>
    <artifactId>nashorn-core</artifactId>
    <version>15.4</version>
</dependency>
  • 对于Java 8版本,默认包含Nashorn引擎,需检查类加载器配置是否允许访问该引擎。

方案3:自定义后端验证逻辑

在后台handleFileUpload方法中手动验证文件类型,完全绕开组件的allowTypes验证:

public void handleFileUpload(FileUploadEvent event) {
    UploadedFile uploadedFile = event.getFile();
    String fileName = uploadedFile.getFileName();
    String contentType = uploadedFile.getContentType();
    
    // 验证文件是否为PDF
    boolean isPdf = fileName.toLowerCase().endsWith(".pdf") 
            && "application/pdf".equals(contentType);
    
    if (!isPdf) {
        FacesMessage errorMsg = new FacesMessage(FacesMessage.SEVERITY_ERROR, 
            FacesContext.getCurrentInstance().getApplication().getResourceBundle(FacesContext.getCurrentInstance(), "msg")
                .getString("page.application-decisions.invalidFileMessage"), null);
        FacesContext.getCurrentInstance().addMessage(null, errorMsg);
        return;
    }
    
    // 执行后续文件上传逻辑
}

同时移除组件上的allowTypes参数,避免触发组件自带的验证流程。

原因分析

Primefaces 7.0对allowTypes正则表达式的处理逻辑发生变化,会通过JavaScript引擎解析正则来匹配文件名。若运行环境中缺少可用的JS引擎(如Java 11+默认无Nashorn、类加载器无法访问引擎),则会抛出空指针异常。使用逗号分隔的格式时,Primefaces采用简单字符串匹配,无需JS引擎,因此不会报错。

内容的提问来源于stack exchange,提问作者mtmx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.07 02:57:48