能用,但必须明确配置——FileUploadInterceptor不区分文件类型,只解析multipart/form-data并注入File对象;XML上传失败主因是拦截器未生效、maximumSize过小、enctype未设为multipart/form-data或属性名不匹配。

Struts2上传XML文件时,FileUploadInterceptor默认能用吗?
能用,但必须明确配置——FileUploadInterceptor本身不区分文件类型,它只负责解析multipart/form-data请求体、提取File对象并注入到Action属性中。XML只是普通二进制文件,只要HTTP请求格式正确、服务端允许该MIME类型(如text/xml或application/xml),它就能上传成功。
为什么上传XML后Action里File属性为null?
常见原因不是文件类型限制,而是拦截器未生效或配置错位。Struts2的文件上传依赖完整拦截器链,缺一不可:
-
fileUpload拦截器必须显式加入拦截器栈(不能只靠defaultStack默认启用——它虽含fileUpload,但可能被后续配置覆盖) -
maximumSize参数太小(XML虽文本,但带DTD或大量命名空间时体积可能超默认10MB) - 表单
enctype没设成multipart/form-data,或提交方式不是POST - Action中文件属性名、
ContentType属性名、FileName属性名三者必须严格匹配(如字段叫uploadFile,则必须有uploadFile、uploadFileContentType、uploadFileFileName三个属性)
如何安全接收并解析上传的XML文件?
拦截器只负责“传进来”,解析XML是Action自己的事。关键点在于避免XXE攻击(尤其当XML含外部实体引用时):
- 禁用外部实体:用
DocumentBuilderFactory时必须显式关闭setExpandEntityReferences(false)和setFeature("http://apache.org/xml/features/disallow-doctype-decl", true) - 不要用
new SAXBuilder().build(file)这类默认宽松解析器(JDOM 1.x默认开启XXE) - 推荐用
javax.xml.parsers.DocumentBuilder配合白名单特征配置,或直接用XmlInputFactory(StAX)流式解析
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
dbf.setFeature("http://apache.org/xml/features/disallow-doctype-decl", true);
dbf.setFeature("http://xml.org/sax/features/external-general-entities", false);
dbf.setFeature("http://xml.org/sax/features/external-parameter-entities", false);
DocumentBuilder db = dbf.newDocumentBuilder();
Document doc = db.parse(uploadFile); // uploadFile是FileUploadInterceptor注入的File对象
上传大XML文件时性能与内存怎么控?
FileUploadInterceptor会把整个文件先写入临时磁盘(javax.servlet.context.tempdir),再交给Action。但如果你在Action里用DocumentBuilder.parse(File),DOM会全量加载进内存——100MB XML可能吃掉1GB堆空间。
- 改用SAX或StAX逐事件解析,不构建完整树结构
- 检查
struts.multipart.maxSize是否远大于实际需要(比如设为50MB却只传2MB XML,浪费磁盘空间) - 临时文件不会自动清理,需在Action执行完后手动
uploadFile.delete()(注意判空和异常) - 若需校验XML Schema,用
SAXParser配SchemaFactory,别用DocumentBuilder加载后再校验
真正容易被忽略的是:FileUploadInterceptor对XML无特殊逻辑,但开发者常误以为它会自动校验格式或编码——它不会。XML语法错误、编码不匹配(如声明UTF-8但实际是GBK)、BOM头残留,都会导致后续解析失败,而这些错误在拦截器阶段完全不报。










