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日

新哥新奇士橙 LV4
1月26日
214329
2024年11月29日
暂无贡献等级
sunlzh888888 LV29
2023年12月28日
asddwh LV13
2023年12月26日
uni-code_0123 LV1
2023年11月29日
hongdongdong LV14
2023年11月18日
19050126312 LV1
2023年10月19日
luandjustin
2023年7月3日
暂无贡献等级
asadda LV2
2023年6月27日
A-sunny-day LV4
2023年6月10日