您的位置:首页 > 运维架构 > Apache

Apache Commons FileUpload基础教程

2017-04-13 18:23 78 查看

传统API

示例是基于Spring MVC,Apache Commons FileUpload组件版本是1.3.2。

package com.ice.controller;

import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

public class BaseController {
private HttpServletRequest httpServletRequest;
private HttpServletResponse httpServletResponse;
private HttpSession httpSession;

public HttpServletRequest getHttpServletRequest() {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
return servletRequestAttributes.getRequest();
}

public HttpServletResponse getHttpServletResponse() {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
return servletRequestAttributes.getResponse();
}

public HttpSession getHttpSession() {
ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
return servletRequestAttributes.getRequest().getSession();
}
}

package com.ice.controller;

import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.io.FileUtils;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import java.io.File;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Iterator;
import java.util.List;

@Controller
@RequestMapping("/test")
public class TestController extends BaseController {

@RequestMapping("/test1")
public String test1() {
return "test1";
}

@RequestMapping("/test2")
public void test2() throws Exception {
HttpServletRequest httpServletRequest = getHttpServletRequest();
HttpServletResponse httpServletResponse = getHttpServletResponse();
final HttpSession httpSession = httpServletRequest.getSession();

//过程监听器
ProgressListener progressListener = new ProgressListener() {
/**
* @param pBytesRead 已经读取的字节数
* @param pContentLength 总字节数
* @param pItems 字段编号
*/
public void update(long pBytesRead, long pContentLength, int pItems) {
httpSession.setAttribute("pBytesRead", pBytesRead);
httpSession.setAttribute("pContentLength", pContentLength);
httpSession.setAttribute("pItems", pItems);
}
};

DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();
//设置尺寸阈值,单位字节,超过设定值则文件临时写入磁盘,否则保存在内存
diskFileItemFactory.setSizeThreshold(1024 * 1024);
//设置文件写入磁盘时临时保存的目录
diskFileItemFactory.setRepository(new File("d:/"));

ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
//设置允许上传的单个文件最大尺寸,单位字节,-1代表不限制,参数类型是long
servletFileUpload.setFileSizeMax(1024 * 1024 * 10l);
//设置整个请求的大小的最大值,单位字节,-1代表不限制,参数类型是long
servletFileUpload.setSizeMax(1024 * 1024 * 100l);
//设置过程监听器
servletFileUpload.setProgressListener(progressListener);

boolean isMultipartContent = servletFileUpload.isMultipartContent(httpServletRequest);
if (isMultipartContent) {
//开始上传文件并解析请求,按顺序获取各个表单项
List<FileItem> fileItems = servletFileUpload.parseRequest(httpServletRequest);
Iterator<FileItem> fileItemIterator = fileItems.iterator();
while (fileItemIterator.hasNext()) {
FileItem fileItem = fileItemIterator.next();
//如果当前表单项是字段
if (fileItem.isFormField()) {
String fieldName = fileItem.getFieldName();//获取字段名
String value = fileItem.getString("UTF-8");//获取字段值
System.out.println("请求字段:" + fieldName + "=" + value);
}
//如果当前表单项是文件
else {
DiskFileItem diskFileItem = (DiskFileItem) fileItem;
String fieldName = diskFileItem.getFieldName();//获取字段名
String fileName = diskFileItem.getName();//获取浏览器提供的原始文件名
String contentType = diskFileItem.getContentType();//获取文件MIME类型
long sizeInBytes = diskFileItem.getSize();//获取文件大小,单位字节
boolean isInMemory = diskFileItem.isInMemory();//判断文件是否存储在内存中
File storeLocation = diskFileItem.getStoreLocation();
System.out.println("请求字段:" + fieldName);
System.out.println("原始文件名:" + fileName);
System.out.println("MIME类型:" + contentType);
System.out.println("文件大小(字节):" + sizeInBytes);
System.out.println("文件临时保存在内存中?:" + isInMemory);
System.out.println("文件临时保存的路径:" + storeLocation.getAbsolutePath());
try (InputStream inputStream = diskFileItem.getInputStream()) {
FileUtils.copyInputStreamToFile(inputStream, new File("d:/" + fileName));
}
//删除临时文件
diskFileItem.delete();
}
}
}

try (PrintWriter printWriter = httpServletResponse.getWriter()) {
httpServletResponse.setContentType("text/html; charset=utf-8");
printWriter.println("<script>alert('上传成功');</script>");
}
}
}


请求头:

Accept:text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8

Accept-Encoding:gzip, deflate

Accept-Language:zh-CN,zh;q=0.8

Cache-Control:max-age=0

Connection:keep-alive

Content-Length:755

Content-Type:multipart/form-data; boundary=-----------------------------65982022822840

Cookie:JSESSIONID=wg5h37bt3rcr1dcpes14s42jz

Host:localhost:9443

Origin:https://localhost:9443

Referer:https://localhost:9443/ice-web1/test/test1

Upgrade-Insecure-Requests:1

User-Agent:Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/45.0.2454.101 Safari/537.36

请求有效负荷

-----------------------------65982022822840

Content-Disposition: form-data; name="userName"

匿名

-----------------------------65982022822840

Content-Disposition: form-data; name="userAge"

20

-----------------------------65982022822840

Content-Disposition: form-data; name="uploadFile"; filename="测试文件"

Content-Type: application/octet-stream

这里隐藏文件具体内容

-----------------------------65982022822840--

流式API

和传统API不一样的是,传统API中文件在被用户读取前,必须等待被保存在内存或者硬盘中(临时文件),这种方法非常简单,但是另一方面却带来了内存和时间上的额外开销。流式API更佳轻量级,它可以让你牺牲一点便利性以换得理想的性能,文件可以直接从网络输入流中获取。
@RequestMapping("/test3")
public void test3() throws Exception {
HttpServletRequest httpServletRequest = getHttpServletRequest();
HttpServletResponse httpServletResponse = getHttpServletResponse();

//过程监听器
ProgressListener progressListener = new ProgressListener() {
/**
* @param pBytesRead 已经读取的字节数
* @param pContentLength 总字节数
* @param pItems 字段编号
*/
public void update(long pBytesRead, long pContentLength, int pItems) {
System.out.println("已读取字节:" + pBytesRead);
System.out.println("总字节:" + pContentLength);
System.out.println("字段编号:" + pItems);
}
};

DiskFileItemFactory diskFileItemFactory = new DiskFileItemFactory();

ServletFileUpload servletFileUpload = new ServletFileUpload(diskFileItemFactory);
//设置允许上传的单个文件最大尺寸,单位字节
servletFileUpload.setFileSizeMax(1024 * 1024 * 1024 * 10l);
//设置整个请求的大小的最大值,单位字节
servletFileUpload.setSizeMax(1024 * 1024 * 1024 * 100l);
//设置过程监听器
servletFileUpload.setProgressListener(progressListener);

boolean isMultipartContent = servletFileUpload.isMultipartContent(httpServletRequest);
if (isMultipartContent) {
//开始上传文件并解析请求,按顺序获取各个表单项
FileItemIterator fileItemIterator = servletFileUpload.getItemIterator(httpServletRequest);
while (fileItemIterator.hasNext()) {
FileItemStream fileItemStream = fileItemIterator.next();
String name = fileItemStream.getFieldName();
if (fileItemStream.isFormField()) {
try (InputStream inputStream = fileItemStream.openStream()) {
System.out.println("表单字段:" + name + ",值:"
+ Streams.asString(inputStream, "utf-8"));
}
} else {
System.out.println("原始文件名:" + fileItemStream.getName());
System.out.println("MIME类型:" + fileItemStream.getContentType());
try (
//文件输出流
BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(new FileOutputStream("d:/" + fileItemStream.getName()));
//文件输入流
InputStream inputStream = new BufferedInputStream(fileItemStream.openStream());) {
byte[] bytes = new byte[1024 * 8];
int n;
while (-1 != (n = inputStream.read(bytes))) {
bufferedOutputStream.write(bytes, 0, n);
}
}
}
}
}

try (PrintWriter printWriter = httpServletResponse.getWriter()) {
httpServletResponse.setContentType("text/html; charset=utf-8");
printWriter.println("<script>alert('上传成功');</script>");
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: