有关getFiles问题被诟病之后,自己又写了个getStream来替代以此分享

getFiles的问题在于我要文件存数据库时,会先上传到服务器上然后还得删除,于是自己写了个方法,采用的是cos-26Dec2008.jar这个包中的MultipartParser类,具体上代码吧。

这个是自己写的MultipartRequest,

package com.qysoft.rapid.plugin.upload;


import com.oreilly.servlet.multipart.FilePart;
import com.oreilly.servlet.multipart.MultipartParser;
import com.oreilly.servlet.multipart.ParamPart;
import com.oreilly.servlet.multipart.Part;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpUtils;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Map;
import java.util.HashMap;
import java.util.Hashtable;
import java.util.List;
import java.util.ArrayList;
import java.util.Vector;
import java.util.Enumeration;


/**
 * MultipartRequest 改造版,将文件上传改造为流上传至内存
 * @author ght 2020/07/02
 *
 */
public class MultipartRequest extends HttpServletRequestWrapper {
    private List<UploadStream> uploadStreams;
    protected Hashtable parameters;
 
    public MultipartRequest(HttpServletRequest request, int maxPostSize, String encoding) {
        super(request);
        wrapMultipartRequest(request, maxPostSize, encoding);
    }
 
    /**
     * MultipartRequest核心封装方法
     * @param request http请求
     * @param maxPostSize 最大上传大小
     * @param encoding 字符编码
     */
    private void wrapMultipartRequest(HttpServletRequest request, int maxPostSize, String encoding) {
        uploadStreams = new ArrayList<UploadStream>();
        this.parameters = new Hashtable();
        try {
            MultipartParser parser = new MultipartParser(request, maxPostSize, true, true, encoding);
            Vector existingValues;
            if (request.getQueryString() != null) {
                Hashtable queryParameters = HttpUtils.parseQueryString(request.getQueryString());
                Enumeration queryParameterNames = queryParameters.keys();

                while(queryParameterNames.hasMoreElements()) {
                    Object paramName = queryParameterNames.nextElement();
                    String[] values = ((String[])queryParameters.get(paramName));
                    existingValues = new Vector();

                    for(int i = 0; i < values.length; ++i) {
                        existingValues.add(values[i]);
                    }

                    this.parameters.put(paramName, existingValues);
                }
            }
            Part part;
            while ((part = parser.readNextPart()) != null) {
                String name = part.getName();
                if (name == null) {
                    throw new IOException("Malformed input: parameter name missing (known Opera 7 bug)");
                }
                String fileName;
                if (part.isParam()) {
                    ParamPart paramPart = (ParamPart)part;
                    fileName = paramPart.getStringValue();
                    existingValues = (Vector)this.parameters.get(name);
                    if (existingValues == null) {
                        existingValues = new Vector();
                        this.parameters.put(name, existingValues);
                    }

                    existingValues.addElement(fileName);
                }else if (part.isFile()) {
                    FilePart filePart = (FilePart) part;
                    fileName = filePart.getFileName();
                    String contentType = filePart.getContentType();

                    //获取输入流,注意这里的输入流指针位置已经到末尾,不能再使用了,所以要借用内存流,所以不能用以下代码
                    //InputStream is = filePart.getInputStream();
                    
                    // 写到缓存中,使用时创建InputStream进行复用
                    ByteArrayOutputStream baos = new ByteArrayOutputStream();
                    filePart.writeTo(baos);
                    if (fileName != null) {
                        UploadStream uploadStream = new UploadStream(new ByteArrayInputStream(baos.toByteArray()),fileName,contentType);
                        uploadStreams.add(uploadStream);
                    }
                }
            }
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
 
    public List<UploadStream> getStreams() {
        return uploadStreams;
    }



    @Override
    public Enumeration getParameterNames() {
        return this.parameters.keys();
    }

    @Override
    public String getParameter(String name) {
        try {
            Vector values = (Vector)this.parameters.get(name);
            if (values != null && values.size() != 0) {
                String value = (String)values.elementAt(values.size() - 1);
                return value;
            } else {
                return null;
            }
        } catch (Exception var4) {
            return null;
        }
    }

    @Override
    public String[] getParameterValues(String name) {
        try {
            Vector values = (Vector)this.parameters.get(name);
            if (values != null && values.size() != 0) {
                String[] valuesArray = new String[values.size()];
                values.copyInto(valuesArray);
                return valuesArray;
            } else {
                return null;
            }
        } catch (Exception var4) {
            return null;
        }
    }

    @Override
    public Map getParameterMap() {
        Map map = new HashMap();
        Enumeration enumm = this.getParameterNames();
        while(enumm.hasMoreElements()) {
            String name = (String)enumm.nextElement();
            map.put(name, this.getParameterValues(name));
        }

        return map;
    }

}

UploadStream源码

package com.qysoft.rapid.plugin.upload;

import java.io.InputStream;

public class UploadStream {

    private InputStream in;
    private String fileName;
    private String contentType;

    public UploadStream(InputStream in, String fileName, String contentType) {
        this.in = in;
        this.fileName = fileName;
        this.contentType = contentType;
    }

    public InputStream getInputStream() {
        return in;
    }

    public String getFileName() {
        return fileName;
    }

    public String getContentType() {
        return contentType;
    }
}

然后在Controller中调用的方式为

HttpServletRequest request = new MultipartRequest(getRequest(), 100 * 1024 * 1024, "utf-8");
List<UploadStream> uploadStreamList = ((MultipartRequest)request).getStreams();
//这里获取request参数需要上面的request对象来获取,否则直接调用getPara()是获取不到参数的
Map<String, Object> parameters = new HashMap<String, Object>();
for (Enumeration<String> iter = request.getParameterNames(); iter.hasMoreElements();) {
    String paraName = (String) iter.nextElement();
    String paraValue = request.getParameter(paraName);
    parameters.put(paraName, paraValue==null?null: Jsoup.clean(paraValue, Whitelist.basic()));
}

以上为自己倒腾的结果,有疑问的欢迎留言提问。

评论区

山东小木

2020-07-04 17:39

你项目需求 文件就非得存数据库里吗?

JFinal

2020-07-04 22:01

cos 已经升级到了 2020.4 版本,建议升上来

nightseventhunit

2020-07-06 16:56

@山东小木 需求是这样的,存数据库里~~~,我也是第一次这么干把文件存数据库里,还是oracle

zzutligang

2020-07-07 14:11

小的图片文件或则word,pdf文档一类的,存数据库是有优势的。没遇到问题的不觉得什么,遇到问题的,头大到崩溃!我现在像头像图片,一些附件文件,只要不是上百兆的文件,都会存在数据库里。如果是大文件,也不要放到web项目里,而是专门做一个静态文件服务器。通过http访问。迁移项目的时候,就知道好处了。

JAdmins

2020-07-15 09:12

@zzutligang 上传的资源当然得与web项目分离;如果只是为了迁移方便,那我倒是不认同你的观点。

zzutligang

2020-07-15 11:39

@JAdmins 每个人做项目都有自己的偏好,似乎并没有绝对的对或则错。你觉得呢!

热门分享

扫码入社