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
相关产品推荐
相关产品推荐

