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

如何升级使用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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 23:50:15