一、文件上传
1.文件上传表单(Html)
Html表单文件上传:
<form
action="${pageContext.request.contextPath}/UploadServlet"
method="POST"
enctype="multipart/form-data">
<input type="text" name="desc"/>
<input type="file" name="testFile1" />
<input type="file" name="testFile2" />
<input type="submit" value="上传"/>
</form>
Http请求post格式:
POST /xxx HTTP/1.1
Host: x.x.x
Content-Length: xxxxxx
Content-Type: multipart/form-data; boundary=BoundarybXA7KWbsgAx0OB7z
--BoundarybXA7KWbsgAx0OB7z
Content-Disposition: form-data; name="desc"
...文本内容...
--BoundarybXA7KWbsgAx0OB7z
Content-Disposition: form-data; name="testFile1"; filename="文件1.zip"
Content-Type: application/octet-stream
...文件内容...
--BoundarybXA7KWbsgAx0OB7z
Content-Disposition: form-data; name="testFile2"; filename="文件2.zip"
Content-Type: application/octet-stream
...文件内容...
--BoundarybXA7KWbsgAx0OB7z--
2.Servlet文件上传
方法一.使用Servlet3.0规范接口
@MultipartConfig(
fileSizeThreshold=(可选), 内存缓冲区大小
location=(可选), 临时文件目录,调用Part.write(..)会自动清除临时文件
maxFileSize=(可选), 单个文件最大值, 超过则抛出IllegalStateException异常
maxRequestSize=(可选) 总上传的最大值, 超过则抛出IllegalStateException异常
)
public class UploadServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response){
Collection<Part> part = request.getParts();
for (Part p : part) {
if (p.getSubmittedFileName() == null) {
// 非文件Part
StringBuilder value = new StringBuilder();
BufferedReader br = new BufferedReader(new InputStreamReader(p.getInputStream(), "utf-8"));
String line;
while ((line = br.readLine()) != null) {
value.append(line);
}
System.out.println(p.getName() + ": " + value.toString());
} else {
// 文件Part
String uuidName = UUID.randomUUID().toString() + "_" + p.getSubmittedFileName();
// 参数是绝对路径+文件名,若只传文件名,则存储在location=目录
p.write(getServletContext().getRealPath("/WEB-INF/upload")+uuidName);
}
}
}
}
方法二.使用Apache-commons-fileupload开源工具
commons-fileupload和commons-io两个包,fileupload依赖io包
public class UploadServlet extends HttpServlet {
protected void doGet(HttpServletRequest request, HttpServletResponse response){
if (!ServletFileUpload.isMultipartContent(request)) {
throw new RuntimeException("请用Multipart表单上传!");
}
// 1.创建ServletFileUpload,设定内存缓冲区大小(默认10k),设定临时文件目录(默认操作系统临时目录)
DiskFileItemFactory factory = new DiskFileItemFactory(100*1024,new File(xx/temp));
ServletFileUpload fileUpload = new ServletFileUpload(factory);
fileUpload.setFileSizeMax(1024*1024*10); // 单个文件不大于10M
fileUpload.setSizeMax(1024*1024*100); // 总大小不大于100M
fileUpload.setHeaderEncoding("utf-8"); // 设置编码集
// 2.监听文件上传进度
fileUpload.setProgressListener(new ProgressListener(){
public void update(long bytesRead, long contentLength, int items) {
System.out.print("当前是第" + items + "个上传项, 总大小" + length/1024f + "KB, 已经读取" + read/1024f+ "KB");
System.out.println();
}
});
// 4.获取所有FileItem
for (FileItem fileItem : (List<FileItem>) fileUpload.parseRequest(request)) {
if (fileItem.isFormField()) {
// 字符项
String name = fileItem.getFieldName();
String value = fileItem.getString("utf-8");
System.out.println(name + ":" + value);
} else {
// 文件项
String uuidName = UUID.randomUUID().toString() + "_" + fileItem.getName();
// 生成随机目录path(目录分离)
char[] hashPath = Integer.toHexString(uuidName.hashCode()).toCharArray();
String path = getServletContext().getRealPath("WEB-INF/upload");
for (char p : hashPath) path += "/" + p;
new File(path).mkdirs();
// 存储文件
InputStream in = fileItem.getInputStream();
OutputStream out = new FileOutputStream(new File(path, uuidName));
byte[] b = new byte[100*1024];
int len;
while ((len=in.read(b))!=-1) {
out.write(b, 0, len);
}
// 删除临时文件
fileItem.delete();
}
}
}
}
二、文件下载
// Http响应头,要求浏览器以附件形式打开
response.setHeader("Content-Disposition", "attachment;filename="+URLEncoder.encode(filename,"utf-8"));
// MIME类型
response.setContentType(getServletContext().getMimeType(filename));
简书: http://www.jianshu.com/p/fc3198a7ea99
CSDN博客: http://blog.csdn.net/qq_32115439/article/details/54800610
GitHub博客:http://lioil.win/2017/01/31/Servlet-File.html
Coding博客:http://c.lioil.win/2017/01/31/Servlet-File.html