使用post提交multipart/form-data数据,后台如何获取file文件之外的请求数据(转载)

原文地址:https://blog.csdn.net/lian_zhihui1984/article/details/6822201

post方式(enctype为multipart/form-data,多用于文件上传) 
表单数据都保存在http的正文部分,各个表单项之间用boundary隔开。格式类似于下面这样:用request.getParameter是取不到数据的,这时需要通过request.getInputStream来取数据,不过取到的是个InputStream,所以无法直接获取指定的表单项(需要自己对取到的流进行解析,才能得到表单项以及上传的文件内容等信息)。这种需求属于比较共通的功能,所以有很多开源的组件可以直接利用。比如:apache的fileupload组件,smartupload等。通过这些开源的upload组件提供的API,就可以直接从request中取得指定的表单项了。
 

当提交表单里包含文件上传的时候,即Form的enctype属性值为multipart/form-data时,后台是无法像普通表单那样通过request.getParameter来获取用户提交的数据的。(说实话,我经常因为忘记这个问题而浪费好多调查时间。难过

这时候,当然可以通过解析提交到服务器的数据流来得到数据了,但是这样不但麻烦而且容易出错。

最好的方式是使用第三方的jar包获取数据,这方面有很多现成的成熟优秀的jar包。最常用的时以下三个:

apache的commons-fileupload : http://commons.apache.org/fileupload/

O'Reilly的cos: http://www.servlets.com/cos/index.html

jspsmart的SmartUpload:官方不提供下载了,google搜吧。

其中,据评测效率最高的是COS,最慢的是SmartUpload;最常用的是common-upload;文件太大时SmartUpland会崩溃。

网上有人测试过,当上传文件200M时,COS比apache的fileupload组件快20秒

  • 可以使用jfinal开源项目上传到maven仓库的jar依赖,,,其实也就是引用的原来的项目,进行封装
<dependency>
    <groupId>com.jfinal</groupId>
    <artifactId>cos</artifactId>
    <version>26Dec2008</version>
</dependency>
  • 这是apache的文件上传解析工具依赖
<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.2.2</version>
</dependency>

 

 1. common-upload示例代码:

// 判断enctype属性是否为multipart/form-data
boolean isMultipart = ServletFileUpload.isMultipartContent(request);
 
// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory();
 
// 当上传文件太大时,因为虚拟机能使用的内存是有限的,所以此时要通过临时文件来实现上传文件的保存
// 此方法是设置是否使用临时文件的临界值(单位:字节)
factory.setSizeThreshold(yourMaxMemorySize);
 
// 与上一个结合使用,设置临时文件的路径(绝对路径)
factory.setRepository(yourTempDirectory);
 
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
 
// 设置上传内容的大小限制(单位:字节)
upload.setSizeMax(yourMaxRequestSize);
 
// Parse the request
List<?> items = upload.parseRequest(request);
 
Iterator iter = items.iterator();
while (iter.hasNext()) {
    FileItem item = (FileItem) iter.next();
 
    if (item.isFormField()) {
        //如果是普通表单字段
        String name = item.getFieldName();
            String value = item.getString();
            ...
    } else {
        //如果是文件字段
        String fieldName = item.getFieldName();
            String fileName = item.getName();
            String contentType = item.getContentType();
            boolean isInMemory = item.isInMemory();
            long sizeInBytes = item.getSize();
            ...
            
            // Process a file upload
                if (writeToFile) {
                    File uploadedFile = new File(...);
                    item.write(uploadedFile);
                } else {
                    InputStream uploadedStream = item.getInputStream();
                    ...
                    uploadedStream.close();
                }
    }
}

2. cos示例代码:

// 设置大小限制(单位:字节)
final int permitedSize = 314572800;
 
try {               
    String type = "";
    String name = "";
    String originalFilename = "";
    String extension1 = "";
    String extension2 = "";
    String filename = "";
    
    //上传目录
    String strDirectory = "files";
    String uploadPath = request.getRealPath("//WEB-INF//"+strDirectory+"//");
    
    // 获取句柄
    MultipartRequest multipartRequest = new MultipartRequest(request, uploadPath, 
                     permitedSize, "ISO-8859-1", new DefaultFileRenamePolicy()); 
        
    // 取得文件
    Enumeration files = multipartRequest.getFileNames();       
        
    // 取得文件详细信息 
    while (files.hasMoreElements()) { 
           name = (String)files.nextElement();
           type = multipartRequest.getContentType(name); 
           filename = multipartRequest.getFilesystemName(name); 
           originalFilename = multipartRequest.getOriginalFileName(name);           
           File currentFile = multipartRequest.getFile(name);
           ...
    }
    
    // 取得其它非文件字段
    Enumeration params = multipartRequest.getParameterNames();
    
    while (params.hasMoreElements()) {
        String name = (String)params.nextElement();
        String value = multi.getParameter(name);
        ...
    }                      
} catch (Exception exception) { 
    response.sendError(response.SC_METHOD_NOT_ALLOWED);
} finally { 
    if (out != null) {out.close();} 
}

3. SmartUpload示例代码:

smartupload mysmartupload = new smartupload();
mysmartupload.initialize(this.getServletConfig(), request, response);
// 设置文件大小限制(单位:字节)
mysmartupload.setMaxFileSize(10000000);           
// 设置总上传数据总大小(单位:字节)
mysmartupload.setTotalMaxFileSize(20000000);
// 设置允许的文件扩展名
mysmartupload.setAllowedFilesList("jpg,png,gif,bmp,jpeg");
// 设置不允许的文件扩展名
mysmartupload.setDeniedFilesList("exe,bat,jsp,htm,html,,");
 
try {
    mysmartupload.upload();
} catch (smartuploadException e1) {
    e1.printStackTrace();
}
 
// 读取其它非文件上传字段
com.jspsmart.upload.Request req = mysmartupload.getRequest();
String title = req.getParameter("dest");
 
// 保存文件
for (int i = 0; i < mysmartupload.getFiles().getCount(); i++) {
    com.jspsmart.upload.File file = mysmartupload.getFiles().getFile(i);
    
    if (file.isMissing()) continue;
 
    try {
        file.saveAs("yourSavePath" + file.getFileName());
    } catch (smartuploadException e) {
        e.printStackTrace();
    }
}

 

posted @ 2018-08-30 18:16  海绵般汲取  阅读(15705)  评论(0)    收藏  举报