文件上传原理

在TCP/IP中,最早出现的文件上传机制是FTP。它是将文件由客户端发送到服务器的标准机制。
但是JSP编程中不能使用FTP方法来上传文件,这是由JSP运行机制所决定的。

JSP中上传文件的解决方式:
通过为表单元素设置
Method = “post”
enctype = “multipart/form-data”
属性,让表单提交的数据以二进制编码的方式提交,在接受此请求的Servlet中用二进制流来获取内容,就可以取得上传文件的内容,从而实现文件的上传。

表单中enctype属性说明:
enctype属性的值有三种:

  • application/x-www-form=urlencoded:这是默认编码方式,它只处理表单域里的value属性值,采用这种编码方式的表单会将表单域的值处理成URL编码方式。
  • multipart/form-data:这种编码方式的表单会以二进制流的方式来处理表单数据,这种编码方式会把文件域指定文件的内容也封装到请求参数里。
  • text/plain:这种方式主要适用于直接通过表单发送邮件的方式

文件上传的实现步骤:

  1. 环境搭建:配置web.xml创建UploadServlet
  2. 前台页面配置:Form的method设置为post,enctype设置为multipart/form-data
  3. 后台Servlet实现:保存上传文件

上传文件的后台实现的具体步骤:

  1. 获取request当中的流信息,保存到临时文件
  2. 从临时文件当中得到上传的文件名及文件内容起止位置
  3. 根据文件起止位置,读取上传文件内容,保存到本地

文件的上传:

//文件上传private void uploadFile(HttpServletRequest request, HttpServletResponse response)throws IOException, FileNotFoundException, ServletException {// 从request当中获取流信息InputStream is = request.getInputStream();// 在本地创建临时文件String tempFileName = "C:\\Users\\Administrator\\Desktop\\tempFile";File tempFile = new File(tempFileName);// 将request请求中的所有信息写入临时文件中FileOutputStream fos = new FileOutputStream(tempFile);byte[] b = new byte[1024];int n;while ((n = is.read(b)) != -1) {fos.write(b, 0, n);}fos.close();is.close();// 获取临时文件中的上传文件的文件名RandomAccessFile randomFile = new RandomAccessFile(tempFile, "r");randomFile.readLine();// 读取第一行数据String str = randomFile.readLine();// 读取第二行的内容int beginIndex = str.lastIndexOf("\\") + 1;System.out.println("开始位置:"+beginIndex);int endIndex = str.lastIndexOf("\"");String filename = str.substring(beginIndex, endIndex);System.out.println("文件名:"+filename);//获取文件内容的开始位置randomFile.seek(0);//重新将定位文件指针定位到文件头long startPosition = 0;int i = 1;while((n = randomFile.readByte())!=-1&&i<=4){if(n=='\n'){startPosition = randomFile.getFilePointer();i++;}}startPosition = randomFile.getFilePointer()-1;//获取文件内容的结束位置randomFile.seek(randomFile.length());//定义文件指针到文件结尾long endPosition = randomFile.getFilePointer();int j = 1;while(endPosition>=0&&j<=2){endPosition--;randomFile.seek(endPosition);if(randomFile.readByte()=='\n'){j++;}}endPosition = endPosition-1;//设置保存上传文件的路径String realPath = getServletContext().getRealPath("/")+"images";System.out.println("上传文件的路径:"+realPath);File fileupload = new File(realPath);if(!fileupload.exists()){fileupload.mkdir();}File saveFile = new File(realPath,filename);RandomAccessFile randomAccessFile = new RandomAccessFile(saveFile, "rw");//从临时文件当中读取文件内容(根据起止位置获取)randomFile.seek(startPosition);while(startPosition<endPosition){randomAccessFile.write(randomFile.readByte());startPosition = randomFile.getFilePointer();}//关闭输入输出流、删除临时文件randomFile.close();randomAccessFile.close();tempFile.delete();request.setAttribute("result", "上传成功!");RequestDispatcher dispatcher = request.getRequestDispatcher("jsp/01.jsp");dispatcher.forward(request, response);}

文件下载原理

文件下载的步骤:

  1. 需要通过HttpServletResponse.setContentType方法设置Content-Type头字段的值,位浏览器无法使用某种方式或激活某个程序来处理的MIME类型,例如:“application/octet-stream”或“application/x-msdownload”等。
  2. 需要通过HttpServletResponse.setHeader方法设置Content-Disposition头的值为“attachment;filename=”文件名””。
  3. 读取下载文件,调用HttpServletResponse.getOutputStream方法返回的ServletOutputStream对象来向客户端写入附件文件内容。

实现步骤:

  1. 前台页面开发:通过超链接的方式发起文件下载请求
  2. 配置web.xml文件:配置web.xml,创建DownloadServlet
  3. 后台Servlet实现:设置响应类型及响应头输出流写入文件内容

批量文件下载:

// 批量下载文件private void downMore(HttpServletRequest req, HttpServletResponse resp) throws IOException {resp.setContentType("application/x-msdownload");resp.setHeader("Content-Disposition", "attachment;filename=test.zip");String path = getServletContext().getRealPath("/") + "images/";String[] filenames = req.getParameterValues("filename");String str = "";String rt = "/r/n";ZipOutputStream zos = new ZipOutputStream(resp.getOutputStream());for (String filename : filenames) {str += filename + rt;File file = new File(path+filename);zos.putNextEntry(new ZipEntry(filename));FileInputStream fis = new FileInputStream(file);byte[] b = new byte[1024];int n = 0;while ((n = fis.read(b)) != -1) {zos.write(b, 0, n);}zos.flush();fis.close();}zos.setComment("download success:" + rt + str);zos.flush();zos.close();}

单文件下载:

// 下载一个文件private void downOne(HttpServletRequest request, HttpServletResponse response)throws FileNotFoundException, IOException, ServletException {// 获取文件下载路径String path = getServletContext().getRealPath("/") + "images/";System.out.println("要下载的文件路径地址:" + path);String filename = request.getParameter("filename");File file = new File(path + filename);if (file.exists()) {// 设置响应类型response.setContentType("application/x-msdownload");// 设置头信息(作用:以附件的形式打开我们的下载文件,并且指定了附件的名称,这样下载的时候文件名就是这里设置的文件名称了)response.setHeader("Content-Dispostion", "attachment;filename=\"" + filename + "\"");InputStream is = new FileInputStream(file);ServletOutputStream sos = response.getOutputStream();byte[] b = new byte[1024];int n;while ((n = is.read(b)) != -1) {sos.write(b, 0, n);}// 关闭流释放资源sos.close();is.close();} else {request.setAttribute("errorResult", "文件不存在,下载失败!");RequestDispatcher dispatcher = request.getRequestDispatcher("jsp/01.jsp");dispatcher.forward(request, response);}}

使用SmartUpload实现文件的上传和下载

1.使用该组件可以轻松的实现上传文件类型的限制,也可以轻易的取得文件上传的名称、后缀、大小等。
2.SmartUpload本身也是一个系统提供的jar包,直接将此包放到classpath下即可,也可以拷贝到tomcat_home\lib目录中

使用SmartUpload实现文件的批量上传:

private void uploadFiles(HttpServletRequest request, HttpServletResponse response)throws ServletException, IOException {//设置上传文件保存路径String filePath = getServletContext().getRealPath("/")+"images";System.out.println("上传到的文件路径地址:"+filePath);File file = new File(filePath);if(!file.exists()){file.mkdir();}String result = "上传成功!";SmartUpload su = new SmartUpload();//初始化对象su.initialize(getServletConfig(), request, response);//设置上传文件的大小(10M)su.setMaxFileSize(1024*1024*10);//设置上传的所有文件的大小(100M)su.setTotalMaxFileSize(1024*1024*100);//设置上传文件的的类型su.setAllowedFilesList("txt,jpg,gif");//设置禁止上传文件的类型try {su.setDeniedFilesList("rar,jsp,js");//上传文件su.upload();//将上传文件保存在文件夹中(返回的是上传的文件的个数)int count = su.save(filePath);System.out.println("上传成功了"+count+"个文件!");} catch (Exception e) {result = "上传失败!";if(e.getMessage().indexOf("1015")!=-1){result = "上传失败:上传文件类型不正确!";}else if(e.getMessage().indexOf("1010")!=-1){result = "上传失败:上传文件的类型不正确!";}else if(e.getMessage().indexOf("1105")!=-1){result = "上传失败:上传文件的大小大于允许上传的最大值!";}else if(e.getMessage().indexOf("1110")!=-1){result = "上传失败:上传文件的总大小大于允许上传的最大值!";}e.printStackTrace();} //通过SmartUpload获得上传文件的其他属性for(int i=0;i<su.getFiles().getCount();i++){org.lxh.smart.File tempFile = su.getFiles().getFile(i);System.out.println("----------------------");System.out.println("上传的文件名:"+tempFile.getFileName());System.out.println("上传的文件的大小:"+tempFile.getSize());System.out.println("上传的扩展名:"+tempFile.getFileExt());System.out.println("上传的文件的全名:"+tempFile.getFilePathName());System.out.println("----------------------");}request.setAttribute("result", result);request.getRequestDispatcher("jsp/02.jsp").forward(request, response);}

使用SmartUpload实现文件的下载(单文件下载):

//下载一个文件private void downOne(HttpServletRequest request, HttpServletResponse response) {String filename = request.getParameter("filename");SmartUpload su = new SmartUpload();try {su.initialize(getServletConfig(), request, response);su.downloadFile("/images/" + filename);} catch (Exception e) {e.printStackTrace();}}

项目完整代码的Github地址:

文件的上传和下载---学习笔记相关推荐

  1. # nest笔记四:文件的上传与下载

    nest笔记四:文件的上传与下载 nest是基于express之上的,所以,其文件上传和下载的功能,实际上就是express的功能. 下载 文件下载有两种,一个是sendFile,一个是downloa ...

  2. 【前端学习日记】使用HTML实现文件的上传和下载

    文件的上传和下载分别通过表单元素<input>和超链接标签<a>来实现. 文件的上传: 将表单元素<input>的属性type设置为"file" ...

  3. 手把手教你学javaweb(五)文件的上传和下载

    javaweb项目文件的上传和下载 ​ 在进行文件的上传和下载之前,我们先把javaweb项目做一点点的改动,那就是将LoginServlet的跳转由原来的forward方式改为 redirect方式 ...

  4. ASP.NET实现文件的上传和下载

    最近做的一个高校网站中涉及到了上传和下载文件的需求(具体需求为:网站公布的通知,在后台要能给每个通知添加附件,在前台要能显示并下载附件),之前只是学习过关于上传的 理论知识,这里实践了一下下,与大家分 ...

  5. nginx java文件上传_Nginx实现文件的上传和下载

    文件的上传只要保证特殊的地址先到达Nginx,然后通过Nginx指定至指定的服务器即可,目前配置是本机.文件的下载的做法就是把本机的当前目录下面的文件给返回回去. server { listen ; ...

  6. Vue实现Excel模板文件的上传与下载

    Vue实现Excel模板文件的上传与下载 一.前言 越来越多的项目开始使用前后端分离的方式来进行开发了,前端使用的vue来进行页面处理的,所以正常的文件下载和上传肯定是少不了的,因为这也是自己第一次使 ...

  7. java struts2下载文件_Struts2下多文件的上传与下载

    Struts2下多文件的上传与下载 目录 多文件 上传 下载 随意文件java Struts2单例 配置 动态读取 李顺利 在网络上,对于Java处理文件上传和下载的技术比较多,而Struts作为一款 ...

  8. SpringMVC实现文件的上传和下载

    SpringMVC实现文件的上传和下载http://www.bieryun.com/1120.html 前些天一位江苏经贸的学弟跟我留言问了我这样一个问题:"用什么技术来实现一般网页上文件的 ...

  9. Akka实战:HTTP大文件断点上传、下载,秒传

    2019独角兽企业重金招聘Python工程师标准>>> 访问:https://github.com/yangbajing/scala-applications/tree/master ...

最新文章

  1. js -“=”“==”和“===”的区别
  2. spark Bisecting k-means(二分K均值算法)
  3. web项目启动,运行方法
  4. php+ tinymce粘贴word
  5. zookeeper收尾+dubbo前瞻
  6. C语言 泛型链表 如何计算(结构体中各元素)相对内存地址?(字节对齐,结构体对齐)offsetof()函数 ( (struct X*)0 ) -> Y)语法(匿名结构体)
  7. 【Unity】6.1 Unity中的C#脚本基础知识
  8. some demos
  9. 【C++深度剖析教程39】实现C++数组类模板
  10. Timestream开发最佳实践
  11. MongoDB入门(一)——数据库概述
  12. 数据类型oracle,oracle的数据类型
  13. 腾讯云轻量应用服务器怎么用?配置搭建网站教程
  14. 向西,向西,到栖霞去(二)--走马看福山
  15. 电脑蓝屏了,错误代码:0x000000CE: DRIVER_UNLOADED_WITHOUT_CANCELLING_PENDING_OPERATIONS
  16. java学习笔记(二十八)——开发一个小项目(VMeeting3.0)
  17. 20个经典的Java应用
  18. Procreate iPad绘画教程
  19. 国内人脸识别发展到什么地步了?一文带你了解详情
  20. ubuntu20.04里怎么创建.txt文件

热门文章

  1. import lombok 报错_Android上使用Lombok和set、get方法告别
  2. 优化函数html代码,CSS代码优化方法
  3. MongoDB存储文件之GridFS
  4. vue页面引入多个组件的方法
  5. webpack基础webpack-dev-server配置
  6. 最优化方法系列:Adam+SGD-AMSGrad
  7. ANN:ML方法与概率图模型
  8. VTK教程系列:VTK基础及应用开发教程
  9. 文件操作模式扩展、游标操作
  10. Linux编程 8 (挂载mount,查看磁盘df du,搜索grep,压缩zgip,归档tar)