javaWEB文件上传与下载详解编程语言
2023-06-13 09:20:28 时间
对于文件上传,浏览器在上传的过程中是将文件以流的形式提交到服务器端的,如果直接使用Servlet获取上传文件的输入流然后再解析里面的请求参数是比较麻烦,所以一般选择采用apache的开源工具common-fileupload这个文件上传组件。这个common-fileupload上传组件的jar包可以去apache官网上面下载,common-fileupload是依赖于common-io这个包的,所以还需要下载这个包。
上传组件需要有以下几点注意事项
form表单: method=”post” enctype=”multipart/form-data” 属于域: input type=”file” name=”file” size=”50”这两点弄好,显示如下
%@ page contentType="text/html;charset=UTF-8" language="java" % html head title 上传测试 /title /head body form action="DealwithUpload.jsp" method="post" enctype="multipart/form-data" input type="file" name="file" size="50" input type="submit" name="submit" value="提交" /form /body /htmlWEB.xml配置上传路径
关于上传路径也可以直接在代码中写,不过配置在这里方便修改
context-param description Location to store uploaded file /description param-name file-upload /param-name param-value e://temp// /param-value /context-param处理上传的JSP
%@ page contentType="text/html;charset=UTF-8" language="java" % %@ page import="org.apache.commons.fileupload.FileItem,org.apache.commons.fileupload.disk.DiskFileItemFactory, org.apache.commons.fileupload.servlet.ServletFileUpload" % %@ page import="java.io.File" % %@ page import="java.util.Iterator" % %@ page import="java.util.List" % File file ; int maxFileSize = 5000 * 1024; int maxMemSize = 5000 * 1024; ServletContext context = pageContext.getServletContext(); String filePath = context.getInitParameter("file-upload");//得到配置文件中的上传路径 String contentType = request.getContentType();//返回request主体的MIME类型 if ((contentType.contains("multipart/form-data"))) { DiskFileItemFactory factory = new DiskFileItemFactory();//创建一个基于硬盘的FileItem factory.setSizeThreshold(maxMemSize);//设置写入时使用硬盘的最大缓存 factory.setRepository(new File("e://temp//"));//设置上传时使用的临时目录 ServletFileUpload upload = new ServletFileUpload(factory);//创建一个文件上传处理器 upload.setSizeMax( maxFileSize );//设置文件上传最大尺寸,单位B try{ List fileItems = upload.parseRequest(request);//解析复合表单数据,返回一个fileItem的集合,这样的话就可以一次上传多个文件 Iterator i = fileItems.iterator(); out.println(" html out.println(" head out.println(" title JSP File upload /title out.println(" /head out.println(" body //对上传文件进行遍历 while ( i.hasNext () ) FileItem fi = (FileItem)i.next(); if ( !fi.isFormField () )//如果是上传文件类型,因为表单中可能混合着其他输入类型 String fieldName = fi.getFieldName();//返回file String fileName = fi.getName();//返回上传文件名,这里可以自行检验上传文件后缀是否合法,使用String的endWith()即可 boolean isInMemory = fi.isInMemory();// long sizeInBytes = fi.getSize();//返回文件大小 //开始写入文件,文件名是可以自定义的 if( fileName.lastIndexOf("//") = 0 ){ file = new File( filePath , fileName.substring( fileName.lastIndexOf("//"))) ; }else{ file = new File( filePath , fileName.substring(fileName.lastIndexOf("//")+1)) ; fi.write( file ) ; out.println("Uploaded Filename: " + filePath + fileName + " br out.println(" /body out.println(" /html }catch(Exception ex) { System.out.println(ex); }else{ out.println(" html out.println(" head out.println(" title Servlet upload /title out.println(" /head out.println(" body out.println(" p No file uploaded /p out.println(" /body out.println(" /html %
文件的下载参考孤山苍狼的博客,写得很详细,直接拿来用了.
下载的基本思路就是:首先遍历下载目录的所有文件,然后显示到页面上,客户端发出请求下载,,服务器端回应下载.
public class ListFileServlet extends HttpServlet { public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获取上传文件的目录 String uploadFilePath = this.getServletContext().getRealPath("/WEB-INF/upload"); //存储要下载的文件名 Map String,String fileNameMap = new HashMap String,String //递归遍历filepath目录下的所有文件和目录,将文件的文件名存储到map集合中 listfile(new File(uploadFilePath),fileNameMap);//File既可以代表一个文件也可以代表一个目录 //将Map集合发送到listfile.jsp页面进行显示 request.setAttribute("fileNameMap", fileNameMap); request.getRequestDispatcher("/listfile.jsp").forward(request, response); /** * @Method: listfile * @Description: 递归遍历指定目录下的所有文件 * @param file 即代表一个文件,也代表一个文件目录 * @param map 存储文件名的Map集合 */ public void listfile(File file,Map String,String map){ //如果file代表的不是一个文件,而是一个目录 if(!file.isFile()){ //列出该目录下的所有文件和目录 File files[] = file.listFiles(); //遍历files[]数组 for(File f : files){ //递归 listfile(f,map); }else{ /** * 处理文件名,上传后的文件是以uuid_文件名的形式去重新命名的,去除文件名的uuid_部分 file.getName().indexOf("_")检索字符串中第一次出现"_"字符的位置,如果文件名类似于:9349249849-88343-8344_阿_凡_达.avi 那么file.getName().substring(file.getName().indexOf("_")+1)处理之后就可以得到阿_凡_达.avi部分 */ String realName = file.getName().substring(file.getName().indexOf("_")+1); //file.getName()得到的是文件的原始名称,这个名称是唯一的,因此可以作为key,realName是处理过后的名称,有可能会重复 map.put(file.getName(), realName); public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response);
这里简单说一下ListFileServlet中listfile方法,listfile方法是用来列出目录下的所有文件的,listfile方法内部用到了递归,在实际开发当中,我们肯定会在数据库创建一张表,里面会存储上传的文件名以及文件的具体存放目录,我们通过查询表就可以知道文件的具体存放目录,是不需要用到递归操作的,这个例子是因为没有使用数据库存储上传的文件名和文件的具体存放位置,而上传文件的存放位置又使用了散列算法打散存放,所以需要用到递归,在递归时,将获取到的文件名存放到从外面传递到listfile方法里面的Map集合当中,这样就可以保证所有的文件都存放在同一个Map集合当中。
在Web.xml文件中配置ListFileServlet
servlet servlet-name ListFileServlet /servlet-name servlet-class me.gacl.web.controller.ListFileServlet /servlet-class /servlet servlet-mapping servlet-name ListFileServlet /servlet-name url-pattern /servlet/ListFileServlet /url-pattern /servlet-mapping
展示下载文件的listfile.jsp页面如下:
%@ page language="java" import="java.util.*" pageEncoding="UTF-8"% [email protected] prefix="c" uri="http://java.sun.com/jsp/jstl/core" % !DOCTYPE HTML html head title 下载文件显示页面 /title /head body !-- 遍历Map集合 -- c:forEach var="me" items="${fileNameMap}" c:url value="/servlet/DownLoadServlet" var="downurl" c:param name="filename" value="${me.key}" /c:param /c:url ${me.value} a href="${downurl}" 下载 /a br/ /c:forEach /body /html实现文件下载
package me.gacl.web.controller; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.OutputStream; import java.net.URLEncoder; import javax.servlet.ServletException; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; public class DownLoadServlet extends HttpServlet {
public void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //得到要下载的文件名 String fileName = request.getParameter("filename"); //23239283-92489-阿凡达.avi fileName = new String(fileName.getBytes("iso8859-1"),"UTF-8"); //上传的文件都是保存在/WEB-INF/upload目录下的子目录当中 String fileSaveRootPath=this.getServletContext().getRealPath("/WEB-INF/upload"); //通过文件名找出文件的所在目录 String path = findFileSavePathByFileName(fileName,fileSaveRootPath); //得到要下载的文件 File file = new File(path + "//" + fileName); //如果文件不存在 if(!file.exists()){ request.setAttribute("message", "您要下载的资源已被删除!!"); request.getRequestDispatcher("/message.jsp").forward(request, response); return; //处理文件名 String realname = fileName.substring(fileName.indexOf("_")+1); //设置响应头,控制浏览器下载该文件 response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(realname, "UTF-8")); //读取要下载的文件,保存到文件输入流 FileInputStream in = new FileInputStream(path + "//" + fileName); //创建输出流 OutputStream out = response.getOutputStream(); //创建缓冲区 byte buffer[] = new byte[1024]; int len = 0; //循环将输入流中的内容读取到缓冲区当中 while((len=in.read(buffer)) 0){ //输出缓冲区的内容到浏览器,实现文件下载 out.write(buffer, 0, len); //关闭文件输入流 in.close(); //关闭输出流 out.close(); /** * @Method: findFileSavePathByFileName * @Description: 通过文件名和存储上传文件根目录找出要下载的文件的所在路径 * @param filename 要下载的文件名 * @param saveRootPath 上传文件保存的根目录,也就是/WEB-INF/upload目录 * @return 要下载的文件的存储目录 */ public String findFileSavePathByFileName(String filename,String saveRootPath){ int hashcode = filename.hashCode(); int dir1 = hashcode 0xf; //0--15 int dir2 = (hashcode 0xf0) 4; //0-15 String dir = saveRootPath + "//" + dir1 + "//" + dir2; //upload/2/3 upload/3/5 File file = new File(dir); if(!file.exists()){ //创建目录 file.mkdirs(); return dir; public void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); }
在Web.xml文件中配置DownLoadServlet
servlet servlet-name DownLoadServlet /servlet-name servlet-class me.gacl.web.controller.DownLoadServlet /servlet-class /servlet servlet-mapping servlet-name DownLoadServlet /servlet-name url-pattern /servlet/DownLoadServlet /url-pattern /servlet-mapping
10284.html
cjavaxml相关文章
- 黑马瑞吉外卖之文件上传和下载
- iOS小技能:文件上传和下载(断点下载、断点续传)
- ftp工具类:上传与下载文件
- vue 使用 axios 上传文件 — FormData
- Flask 学习-55.文件上传功能开发
- 【说站】php实现文件的上传和下载
- JAVA 文件上传 和 下载
- 文件上传与下载
- 【VS使用】如何换VS2022背景颜色和分屏观看多文件,还有快捷复制粘贴?
- 【愚公系列】2023年01月 .NET/C#知识点-文件上传与下载
- SpringBoot学习——腾讯云文件上传+删除
- ThinkPHP6.0 判断是否有文件上传
- Java开发之文件上传详解编程语言
- Struts2文件的上传与下载详解编程语言
- java和Struts2实现文件下载和上传详解编程语言
- Struts2文件上传和文件下载详解编程语言
- spring boot上传文件错误The temporary upload location [/tmp/tomcat.******/work/Tomcat/localhost/ROOT] is not valid详解编程语言
- Linux脚本实现文件上传功能(linux上传文件脚本)
- Linux FTP上传文件报错解决方法(linuxftp无法上传)
- Linux文件传输指南:快速上传和下载文件的方法(如何把文件传到linux)
- MSSQL注入漏洞防范之文件上传安全(mssql注入上传)
- 无组件实现文件上传/下载
- 文件上传类
- 用PHP实现文件上传二法
- 让你同时上传1000个文件(一)