Java 二阶段 文件上传与下载

tech2023-01-08  120

文件上传与下载

1.上传文件

@WebServlet(name = "UploadingServlet", value = "/uploading") @MultipartConfig() public class UploadingServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); //获取绝对路径名 String realPath = request.getServletContext().getRealPath("/upload"); File dir = new File(realPath); //创建upload文件夹 if (!dir.exists()) { dir.mkdirs(); } //获取数据 Collection<Part> parts = request.getParts(); //判断表单元素是普通字段,还是文件 for (Part part : parts) { String submittedFileName = part.getSubmittedFileName(); if (submittedFileName == null) { String name = part.getName(); String value = request.getParameter(name); System.out.println(name+"--"+value); }else { System.out.println(submittedFileName); part.write(realPath + File.separator + submittedFileName); //删除part part.delete(); out.write(submittedFileName+"上传成功..."); } } } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doPost(request, response); } }

但是根据表单元素的名字来创建文件,不同的浏览器会有不同的表示。 IE浏览器: 所以

@WebServlet(name = "UploadingServlet", value = "/uploading") @MultipartConfig() public class UploadingServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); //获取绝对路径名 String realPath = request.getServletContext().getRealPath("/upload"); File dir = new File(realPath); //创建upload文件夹 if (!dir.exists()) { dir.mkdirs(); } //获取数据 Collection<Part> parts = request.getParts(); //判断表单元素是普通字段,还是文件 for (Part part : parts) { String submittedFileName = part.getSubmittedFileName(); if (submittedFileName == null) { String name = part.getName(); String value = request.getParameter(name); System.out.println(name+"--"+value); }else { //从请求头中获取文件 String header = part.getHeader("content-disposition"); //截取 String filename = header.substring(header.lastIndexOf("filename=") + 10, header.length() - 1); filename = filename.substring(filename.lastIndexOf("\\")+1); System.out.println(filename); part.write(realPath + File.separator + filename); //删除part part.delete(); out.write(filename+"上传成功..."); } } }

如果是不同的用户上传了相同的文件会覆盖,所以应该创建不同名称的文件。定义一个工具类,来生成不同的文件名

//创建新的文件名 public static String makeNewFileName(String filename) { //UUID 统一唯一标识码,认32位的16进制,比如:2d990e71-f5cf-476e-9e31-0dc7ad681638,把“-”去掉,就是一个32位的字符串 String uuid = UUID.randomUUID().toString().replace("-", ""); return uuid = uuid+"_"+filename; } @WebServlet(name = "UploadingServlet", value = "/uploading") @MultipartConfig() public class UploadingServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); //获取绝对路径名 String realPath = request.getServletContext().getRealPath("/upload"); File dir = new File(realPath); //创建upload文件夹 if (!dir.exists()) { dir.mkdirs(); } //获取数据 Collection<Part> parts = request.getParts(); //判断表单元素是普通字段,还是文件 for (Part part : parts) { String submittedFileName = part.getSubmittedFileName(); if (submittedFileName == null) { String name = part.getName(); String value = request.getParameter(name); System.out.println(name+"--"+value); }else { //从请求头中获取文件 String header = part.getHeader("content-disposition"); //截取 String filename = header.substring(header.lastIndexOf("filename=") + 10, header.length() - 1); filename = filename.substring(filename.lastIndexOf("\\")+1); //生成新的文件名 String newFileName = UploadUtils.makeNewFileName(filename); System.out.println(newFileName); part.write(realPath + File.separator + newFileName); //删除part part.delete(); out.write(filename+"上传成功..."); } } }

还有问题,如果都往upload一个文件夹里存放文件,读1M的文件,和读1000个1k的文件,肯定是读1M的文件快,所以我们要让他们存放在不同的文件夹中,可以根据上传时间来设置文件夹。我则采用了另一种方式,通过新的文件名创建新的文件夹。我创建了一个生成新的路径的方法。

//生成新的路径,path是upload的路径。filename是新的文件名。 public static String makeNewPath(String path, String filename) { int num = filename.hashCode(); int path1 = num&0xf; int path2 = (num>>4)&0xf; String newPath = path + File.separator +path1 +File.separator +path2; File dir = new File(newPath); if(!dir.exists()) { dir.mkdirs(); } return newPath; } @WebServlet(name = "UploadingServlet", value = "/uploading") @MultipartConfig() public class UploadingServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); //获取绝对路径名 String realPath = request.getServletContext().getRealPath("/upload"); File dir = new File(realPath); //创建upload文件夹 if (!dir.exists()) { dir.mkdirs(); } //获取数据 Collection<Part> parts = request.getParts(); //判断表单元素是普通字段,还是文件 for (Part part : parts) { String submittedFileName = part.getSubmittedFileName(); if (submittedFileName == null) { String name = part.getName(); String value = request.getParameter(name); System.out.println(name+"--"+value); }else { //从请求头中获取文件 String header = part.getHeader("content-disposition"); //截取 String filename = header.substring(header.lastIndexOf("filename=") + 10, header.length() - 1); filename = filename.substring(filename.lastIndexOf("\\")+1); //生成新的文件名 String newFileName = UploadUtils.makeNewFileName(filename); System.out.println(newFileName); //生成新的文件路径 String newFilePath = UploadUtils.makeNewPath(realPath, newFileName); part.write(newFilePath + File.separator + newFileName); //删除part part.delete(); out.write(filename+"上传成功..."); } } }

我们还没有判断如果上传的文件为空,应该跳过,我们还可以限制上传文件的格式。

@WebServlet(name = "UploadingServlet", value = "/uploading") @MultipartConfig() public class UploadingServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); //添加接受的文件的格式 List<String> allowExts = new ArrayList<>(); allowExts.add("png"); allowExts.add("jpg"); allowExts.add("jpeg"); //获取绝对路径名 String realPath = request.getServletContext().getRealPath("/upload"); File dir = new File(realPath); //创建upload文件夹 if (!dir.exists()) { dir.mkdirs(); } //获取数据 Collection<Part> parts = request.getParts(); //判断表单元素是普通字段,还是文件 for (Part part : parts) { String submittedFileName = part.getSubmittedFileName(); if (submittedFileName == null) { String name = part.getName(); String value = request.getParameter(name); System.out.println(name+"--"+value); }else { //文件是空的 if(submittedFileName.equals("")){ response.getWriter().write("文件不能为空..."); continue; } //从请求头中获取文件 String header = part.getHeader("content-disposition"); //截取 String filename = header.substring(header.lastIndexOf("filename=") + 10, header.length() - 1); filename = filename.substring(filename.lastIndexOf("\\")+1); //判断是否符合接受的文件格式 String ext = filename.substring(filename.lastIndexOf(".")+1); if(!allowExts.contains(ext)){ response.getWriter().write("文件格式不符合要求..."); continue; } //生成新的文件名 String newFileName = UploadUtils.makeNewFileName(filename); System.out.println(newFileName); //生成新的文件路径 String newFilePath = UploadUtils.makeNewPath(realPath, newFileName); part.write(newFilePath + File.separator + newFileName); //删除part part.delete(); out.write(filename+"上传成功..."); } } }

最后我们还要设置一下上传文件的大小。只需在注解中添加属性就可以

@MultipartConfig(maxFileSize = 1024*1024*5, maxRequestSize = 1024*1024*20)

单个文件不超过5M,全部上传文件不超过20M,如果超出了这个界限,会出现500错误页面。所以我们可以设计一个错误界面,去显示这个具体的错误。

还有个问题,我们存文件的地址是不安全的,可以通过路径能访问到,所以我们可以把文件放到WEB-INF文件夹中,这个是不能通过浏览器访问的,但可以通过Servlet来访问。所以说是安全的

最终版

@WebServlet(name = "UploadingServlet", value = "/uploading") @MultipartConfig(maxFileSize = 1024*1024*5, maxRequestSize = 1024*1024*20) public class UploadingServlet extends HttpServlet { protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { request.setCharacterEncoding("utf-8"); response.setContentType("text/html;charset=utf-8"); PrintWriter out = response.getWriter(); //添加接受的文件的格式 List<String> allowExts = new ArrayList<>(); allowExts.add("png"); allowExts.add("jpg"); allowExts.add("jpeg"); //获取绝对路径名 String realPath = request.getServletContext().getRealPath("/WEB-INF/upload"); File dir = new File(realPath); //创建upload文件夹 if (!dir.exists()) { dir.mkdirs(); } //获取数据 Collection<Part> parts = request.getParts(); //判断表单元素是普通字段,还是文件 for (Part part : parts) { String submittedFileName = part.getSubmittedFileName(); if (submittedFileName == null) { String name = part.getName(); String value = request.getParameter(name); System.out.println(name+"--"+value); }else { //文件是空的 if(submittedFileName.equals("")){ response.getWriter().write("文件不能为空..."); continue; } //从请求头中获取文件 String header = part.getHeader("content-disposition"); //截取 String filename = header.substring(header.lastIndexOf("filename=") + 10, header.length() - 1); filename = filename.substring(filename.lastIndexOf("\\")+1); //判断是否符合接受的文件格式 String ext = filename.substring(filename.lastIndexOf(".")+1); if(!allowExts.contains(ext)){ response.getWriter().write("文件格式不符合要求..."); continue; } //生成新的文件名 String newFileName = UploadUtils.makeNewFileName(filename); System.out.println(newFileName); //生成新的文件路径 String newFilePath = UploadUtils.makeNewPath(realPath, newFileName); part.write(newFilePath + File.separator + newFileName); //删除part part.delete(); out.write(filename+"上传成功..."); } } }
最新回复(0)