package com.byzx.web.servlet;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Calendar;
import java.util.Iterator;
import java.util.List;
import java.util.UUID;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadBase;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.ProgressListener;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
/**
* 处理文件上传
*
* @author wangkun
* @create 2017-12-27
**/
public class UploadServlet extends HttpServlet {
private static final long serialVersionUID = 1L;
@Override
protected void doGet(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
response.setContentType("text/html;charset=UTF-8");
PrintWriter out = response.getWriter();
// 设置文件上传基本路径
String savePath = this.getServletContext().getRealPath(
"/WEB-INF/uploadFiles");
// 设置临时文件路径
String tempPath = this.getServletContext().getRealPath(
"/WEB-INF/tempFiles");
File tempFile = new File(tempPath);
if (!tempFile.exists()) {
tempFile.mkdir();
}
// 计算成功上传文件个数
int successCount = 0;
// 定义异常消息
String errorMessage = "";
// 创建file items工厂
DiskFileItemFactory factory = new DiskFileItemFactory();
// 设置缓冲区大小
factory.setSizeThreshold(1024 * 100);
// 设置临时文件路径
factory.setRepository(tempFile);
// 创建文件上传处理器
ServletFileUpload upload = new ServletFileUpload(factory);
// 监听文件上传进度
ProgressListener progressListener = new ProgressListener() {
public void update(long pBytesRead, long pContentLength, int pItems) {
System.out.println("正在读取文件: " + pItems);
if (pContentLength == -1) {
System.out.println("已读取: " + pBytesRead + " 剩余0");
} else {
System.out.println("文件总大小:" + pContentLength + " 已读取:"
+ pBytesRead);
}
}
};
upload.setProgressListener(progressListener);
// 解决上传文件名的中文乱码
upload.setHeaderEncoding("UTF-8");
// 判断提交上来的数据是否是上传表单的数据
if (!ServletFileUpload.isMultipartContent(request)) {
// 按照传统方式获取数据
return;
}
// 设置上传单个文件的大小的最大值,目前是设置为1024*1024字节,也就是1MB
upload.setFileSizeMax(1024 * 1024);
// 设置上传文件总量的最大值,最大值=同时上传的多个文件的大小的最大值的和,目前设置为10MB
upload.setSizeMax(1024 * 1024 * 10);
try {
// 使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项
List<FileItem> items = upload.parseRequest(request);
Iterator<FileItem> iterator = items.iterator();
while (iterator.hasNext()) {
FileItem item = iterator.next();
// 判断jsp提交过来的是不是文件
if (item.isFormField()) {
errorMessage = "请提交文件!";
break;
} else {
// 文件名
String fileName = item.getName();
if (fileName == null || fileName.trim() == "") {
System.out.println("文件名为空!");
break;
}
// 处理不同浏览器提交的文件名带路径问题
fileName = fileName
.substring(fileName.lastIndexOf("\\") + 1);
// 文件扩展名
String fileExtension = fileName.substring(fileName
.lastIndexOf(".") + 1);
// 判断扩展名是否合法
/*if (!validExtension(fileExtension)) {
errorMessage = "上传文件非法!";
item.delete();
break;
}*/
// 获得文件输入流
InputStream in = item.getInputStream();
// 得到保存文件的名称
String saveFileName = createFileName(fileName);
// 得到文件保存路径
String realFilePath = createRealFilePath(savePath,
saveFileName);
// 创建文件输出流
System.out.println("real:" + realFilePath);
FileOutputStream fos = new FileOutputStream(realFilePath);
// 创建缓冲区
byte buffer[] = new byte[1024];
int len = 0;
while ((len = in.read(buffer)) > 0) {
// 写文件
fos.write(buffer, 0, len);
}
// 关闭输入流
in.close();
// 关闭输出流
fos.close();
// 删除临时文件 TODO
System.out.println("delete...");
item.delete();
// 将上传文件信息保存到附件表中 TODO
successCount++;
}
}
} catch (FileUploadBase.FileSizeLimitExceededException e) {
e.printStackTrace();
request.setAttribute("errorMessage", "单个文件超出最大值!!!");
request.getRequestDispatcher("upload.jsp").forward(
request, response);
return;
} catch (FileUploadBase.SizeLimitExceededException e) {
e.printStackTrace();
request.setAttribute("errorMessage", "上传文件的总的大小超出限制的最大值!!!");
request.getRequestDispatcher("upload.jsp").forward(
request, response);
return;
} catch (FileUploadException e) {
e.printStackTrace();
request.setAttribute("errorMessage", "文件上传失败!!!");
request.getRequestDispatcher("upload.jsp").forward(
request, response);
return;
}
request.setAttribute("errorMessage", errorMessage);
if(successCount>0){ // 成功上传文件
out.println("<script>alert('文件上传成功!');location.href='upload.jsp';</script>");
}else{
out.println("<script>location.href='upload.jsp';</script>");
}
}
@Override
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws ServletException, IOException {
doGet(request, response);
}
private boolean validExtension(String fileExtension) {
String[] exts = { "jpg", "txt", "doc", "pdf","png" };
for (int i = 0; i < exts.length; i++) {
if (fileExtension.equals(exts[i])) {
return true;
}
}
return false;
}
private String createFileName(String fileName) {
return UUID.randomUUID().toString() + "_" + fileName;
}
/**
* 根据基本路径和文件名称生成真实文件路径
*
* @param basePath
* @param fileName
* @return
*/
private String createRealFilePath(String basePath, String fileName) {
int hashCode = fileName.hashCode();
int dir1 = hashCode&0xf;// 取1~4位
int dir2 = (hashCode&0xf0)>>4;//取5~8位
String directory = ""+dir1+File.separator+dir2;
File file = new File(basePath,directory);
if(!file.exists()){
file.mkdirs();
}
return file.getAbsolutePath() + File.separator+ fileName;
}
/*private String createRealFilePath(String basePath, String fileName) {
Calendar today = Calendar.getInstance();
String year = String.valueOf(today.get(Calendar.YEAR));
String month = String.valueOf(today.get(Calendar.MONTH) + 1);
String upPath = basePath + File.separator + year + File.separator
+ month + File.separator;
File uploadFolder = new File(upPath);
if (!uploadFolder.exists()) {
uploadFolder.mkdirs();
}
String realFilePath = upPath + fileName;
return realFilePath;
}*/
}