如何升级使用Apache Commons FileUpload DiskFileItem适配Jakarta命名空间?
解决Apache Commons FileUpload v2中DiskFileItem为final无法继承的问题
由于FileUpload v2将DiskFileItem设为final类,无法通过继承扩展功能,你可以用装饰器模式替代继承,实现FileItem接口并内部持有DiskFileItem实例,既保留原有监听逻辑,又不需要修改框架源码。
修改后的代码如下:
import org.apache.commons.fileupload2.core.DiskFileItem; import org.apache.commons.fileupload2.core.FileItem; import java.io.IOException; import java.io.OutputStream; import java.io.File; import java.io.InputStream; import java.io.UnsupportedEncodingException; public class MonitoredDiskFileItem implements FileItem { private final DiskFileItem delegate; private final OutputStreamListener listener; private MonitoredOutputStream mos = null; public MonitoredDiskFileItem(String fieldName, String contentType, boolean isFormField, String fileName, int sizeThreshold, File repository, OutputStreamListener listener) { this.delegate = new DiskFileItem(fieldName, contentType, isFormField, fileName, sizeThreshold, repository); this.listener = listener; } // 以下为FileItem接口方法的委托实现,直接调用delegate的对应方法 @Override public String getFieldName() { return delegate.getFieldName(); } @Override public void setFieldName(String name) { delegate.setFieldName(name); } @Override public boolean isFormField() { return delegate.isFormField(); } @Override public void setFormField(boolean state) { delegate.setFormField(state); } @Override public String getContentType() { return delegate.getContentType(); } @Override public String getName() { return delegate.getName(); } @Override public InputStream getInputStream() throws IOException { return delegate.getInputStream(); } @Override public long getSize() { return delegate.getSize(); } @Override public byte[] get() { return delegate.get(); } @Override public String getString(String encoding) throws UnsupportedEncodingException { return delegate.getString(encoding); } @Override public String getString() { return delegate.getString(); } @Override public void write(File file) throws Exception { delegate.write(file); } @Override public void delete() { delegate.delete(); } @Override public String getContentType(String defaultContentType) { return delegate.getContentType(defaultContentType); } @Override public File getStoreLocation() { return delegate.getStoreLocation(); } @Override public boolean isInMemory() { return delegate.isInMemory(); } // 仅重写需要扩展的getOutputStream方法,保留原有监听逻辑 @Override public OutputStream getOutputStream() throws IOException { if (mos == null) { mos = new MonitoredOutputStream(delegate.getOutputStream(), listener); } return mos; } }
方案说明
- 无需修改FileUpload源码,完全基于官方API实现,避免了自定义编译框架带来的兼容性风险
- 核心逻辑和原有代码一致:仅在获取输出流时包装为带监听的
MonitoredOutputStream - 所有未修改的功能直接委托给内部的
DiskFileItem实例,保证原有行为不变 - 代码结构清晰,后续维护成本低,符合框架将
DiskFileItem设为final的设计意图(限制继承,鼓励组合扩展)
内容的提问来源于stack exchange,提问作者Borea Deitz
相关产品推荐
相关产品推荐

