package com.dream.bamboo; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadBase; import org.apache.commons.fileupload.ProgressListener; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.util.List; import java.util.UUID; /** * @ClassName:UploadServletDetails * @Description:文件上传 * @author :dreambamboo * @date:2018-12-04 */ public class UploadServletDetails extends HttpServlet { @Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { this.doPost(req,resp); } @Override protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //获取上传文件的保存目录,将上传的文件保存在web目录下(但一般为了安全放在web-inf目录下,不允许外界直接访问,保证上传安全) String savePath = this.getServletContext().getRealPath("/WEB-INF/upload"); //上传文件生产的临时文件保存目录 String tmpPath = this.getServletContext().getRealPath("/WEB-INF/temp"); File tmpFile = new File(tmpPath); //判断上传文件的保存目录是否存在 if (!tmpFile.exists() && !tmpFile.isDirectory()){ //如果目录不存在或者不是一个目录则需要创建目录 tmpFile.mkdir(); } //提示信息 String message = ""; //创建DiskFileItemFactory工厂 DiskFileItemFactory dif = new DiskFileItemFactory(); //设置工厂的缓冲区的大侠,当上传文件大小超过缓冲区的大小时,就会生成一个临时文件放到指定的临时目录中 dif.setSizeThreshold(1024*1000); //设置上传时生成的临时文件的保存目录 dif.setRepository(tmpFile); //创建文件上传解析器 ServletFileUpload upload = new ServletFileUpload(dif); //监听文件上传进度 upload.setProgressListener(new ProgressListener() { @Override public void update(long pBytesRead, long pContentLength, int i) { System.out.println("文件大小为:" + pContentLength + ",当前已处理:" + pBytesRead); } }); //解决上传文件名的中文乱码 upload.setHeaderEncoding("UTF-8"); //判断提交上来的数据是否是上传表单的数据 if (!ServletFileUpload.isMultipartContent(req)){ //按照传统方式获取数据 return; } //设置上传单个文件的最大值,目前设置的是1024*1024*2 = 2M upload.setFileSizeMax(2*1024*1024); //设置上传文件的总量的最大值,最大值=同时上传的多个文件的大小的最大值的和,目前设置为10M upload.setSizeMax(10*1024*1024); //使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,每一个FileItem对应一个Form表单的输入项 try { List<FileItem> list = upload.parseRequest(req); //如果fileitem中封装的是普通输入项数据 for (FileItem item:list) { if (item.isFormField()){ String name = item.getFieldName(); //解决普通输入项的数据的中文乱码问题 String value = item.getString("UTF-8"); }else{ //如果fileitem中封装的是上传数据 //得到上传文件的名称 String filename = item.getName(); if (filename == null || filename.trim().equals("")){ continue; } //注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如: c:\a\b\1.txt,而有些只是单纯的文件名,如:1.txt //处理获取到的上传文件的文件名的路径部分,只保留文件名部分 if ((filename.lastIndexOf("\\")) != -1){ filename = filename.substring(filename.lastIndexOf("\\") + 1); } //得到上传文件的扩展名,用于对上传文件的类型进行判断和限制 String fileExtName = filename.substring(filename.lastIndexOf(".") + 1); //获取item中的上传文件的输入流 InputStream inputStream = item.getInputStream(); //得到文件保存的名称 String saveFileName = makeFileName(filename); //得到文件的保存目录 String realSavePath = makeFilePath(saveFileName,savePath); //创建文件输出流 FileOutputStream fileOutputStream = new FileOutputStream(realSavePath + "\\" + saveFileName); //创建一个缓冲区 byte buffer[] = new byte[1024]; //判断输入流中的数据是否已经读完的标识 int len = 0; //循环将输入流中的数据督导缓冲区中,(len = inputStream.read(buffer))>0就表示inputstream里面还有数据 while ((len = inputStream.read(buffer)) > 0){ //使用FileOutputStream输出流将缓冲区中的数据写入到指定的文件目录(savePath + "\\" + filename) 中 fileOutputStream.write(buffer,0,len); } //关闭输出流 fileOutputStream.close(); //关闭输入流 inputStream.close(); //删除处理文件上传时产生的临时文件 //item.delete(); message = "文件上传成功"; } } } catch (FileUploadBase.FileSizeLimitExceededException e){ e.printStackTrace(); req.setAttribute("message","单个文件超出最大值!!!"); req.getRequestDispatcher("/result.jsp").forward(req,resp); return; } catch (FileUploadBase.SizeLimitExceededException e){ e.printStackTrace(); req.setAttribute("message","上传文件的总的大小超出最大值!!!"); req.getRequestDispatcher("/result.jsp").forward(req,resp); return; } catch (Exception e){ message = "文件上传失败"; e.printStackTrace(); } req.setAttribute("message",message); req.getRequestDispatcher("/result.jsp").forward(req,resp); } /** * 为防止一个目录下面出现太多的文件,要使用hash算法打散存储 * @Method:makeFilePath * @param saveFileName 文件名,要根据文件名生成存储路径 * @param savePath 文件存储路径 * @return 新的存储目录 */ private String makeFilePath(String saveFileName, String savePath) { //得到文件名的hashCode值,得到的就是filename这个字符串对象在内存中的地址 int hashcode = saveFileName.hashCode(); int dir1 = hashcode & 0xf;//0--15 int dir2 = (hashcode & 0xf0)>>4;//0--16 //构造新的保存目录 String dir = savePath + "\\" + dir1 + "\\" + dir2; //File既可以代表文件又可以代表目录 File file = new File(dir); //判断目录是否存在 if (!file.exists()){ //如果目录不存在则穿件新的目录 file.mkdirs(); } return dir; } /** * @Method:makeFileName * @Description:生成上传文件的文件名,文件名以:uuid+"_"+文件的原始名称 * @param filename 文件的原始名称 * @return uuid+"_"+文件的原始名称 */ private String makeFileName(String filename) { //为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名 return UUID.randomUUID().toString() + "_" + filename; } }
最近下载更多
19050126312 LV1
2023年10月19日
sanchez1 LV1
2021年10月12日
newplayer LV1
2021年5月22日
17587079094 LV6
2020年11月16日
java_php LV11
2020年10月17日
563066115 LV2
2020年5月7日
user12580 LV5
2020年3月20日
wuwu55 LV1
2019年10月21日
wq66618 LV1
2019年9月3日
zdm568 LV3
2019年8月23日
最近浏览更多
sunlzh888888 LV28
2023年12月28日
asddwh LV12
2023年12月26日
uni-code_0123 LV1
2023年11月29日
hongdongdong LV12
2023年11月18日
19050126312 LV1
2023年10月19日
luandjustin
2023年7月3日
暂无贡献等级
asadda LV2
2023年6月27日
A-sunny-day LV4
2023年6月10日
aaaaaaa陈 LV1
2023年3月21日
一位靓仔路过 LV5
2022年11月4日