Javaweb学习笔记——上传下载文件
一、前言
在Javaweb中,上传下载是经常用到的功能,对于文件上传,浏览器在上传的过程中是以流的过程将文件传给服务器,一般都是使用commons-fileupload这个包实现上传功能,因为commons-fileupload依赖于commons-io这个包,所以需要下载这两个包commons-fileupload-1.2.1.jar和commons-io-1.3.2.jar,笔者已经打包好(点击下载)
1、搭建环境
创建Web项目,将包导入到项目lib下
2、实现文件上传
(第一种上传的方法)
新建upload.jsp页面
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>upload file</title> </head> <body> <!--这里的<%=request.getContextPath()%>是表示项目的绝对路径,也就是说不管你以后将项目拷贝到哪个位置,它都会找到准确的路径 --> <form action="<%=request.getContextPath()%>/uploadServlet" enctype="multipart/form-data" method="post"> <span>选择文件:</span><input type="file" name="file1"> <input type="submit" value="上传"> </form> </body> </html>
新建处理文件上传的Servlet
package com.load; import java.io.File; import java.io.IOException; import java.util.List; import javax.servlet.ServletContext; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.apache.commons.fileupload.FileItem; import org.apache.commons.fileupload.FileUploadException; import org.apache.commons.fileupload.disk.DiskFileItemFactory; import org.apache.commons.fileupload.servlet.ServletFileUpload; @WebServlet("/uploadServlet") public class uploadServlet extends HttpServlet { private static final long serialVersionUID = 1L; public uploadServlet() { super(); } /* fileupload 包中, HTTP 请求中的复杂表单元素都被看做一个 FileItem 对象; * FileItem 对象必须由 ServletFileUpload 类中的 parseRequest() 方法解析 HTTP 请求 * (即被包装之后的 HttpServletRequest 对象)出来,即分离出具体的文本表单和上传文件 * */ protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //通过isMultipartContent()方法:分析请求里面是不是有文件上的请求, boolean isMultipart = ServletFileUpload.isMultipartContent(request); if(isMultipart){ //创建可设置的磁盘节点工厂 DiskFileItemFactory factory = new DiskFileItemFactory(); //获取请求的上下文信息 ServletContext servletContext = request.getServletContext(); //缓存目录,每个服务器特定的目录 File repository = (File) servletContext.getAttribute("javax.servlet.context.tempdir"); //设置服务器的缓存目录 factory.setRepository(repository); //ServletFileUpload 对象的创建需要依赖于 FileItemFactory //工厂将获得的上传文件 FileItem 对象保存至服务器硬盘,即 DiskFileItem 对象。 ServletFileUpload upload = new ServletFileUpload(factory); try { //解析即被包装之后的 HttpServletRequest对象,既是分离文本表单和上传文件(http请求会被包装为HttpServletRequest) List<FileItem> items = upload.parseRequest(request); for(FileItem item:items){ String fieldName = item.getFieldName(); String fileName = item.getName(); String contentType = item.getContentType(); boolean isInMemory = item.isInMemory(); long sizeInBytes = item.getSize(); //实例化一个文件 //request.getRealPath(获取真实路径) File file = new File(request.getRealPath("/")+"/loads"+fileName.substring(fileName.lastIndexOf("\\")+1,fileName.length())); item.write(file); } } catch (FileUploadException e) { e.printStackTrace(); } catch (Exception e) { e.printStackTrace(); } } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
(第二种上传的方法)
新建Jsp页面(同上,只是路径改变下)
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>upload file</title> </head> <body> <!--这里的<%=request.getContextPath()%>是表示项目的绝对路径,也就是说不管你以后将项目拷贝到哪个位置,它都会找到准确的路径 --> <form action="<%=request.getContextPath()%>/uploadservlet1" enctype="multipart/form-data" method="post"> <span>选择文件:</span><input type="file" name="file1"> <input type="submit" value="上传"> </form> </body> </html>
建立Servlet处理上传
package com.load; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.servlet.ServletException; import javax.servlet.annotation.MultipartConfig; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.Part; @WebServlet("/uploadservlet1") @MultipartConfig(location="") public class uploadservlet1 extends HttpServlet { private static final long serialVersionUID = 1L; public uploadservlet1() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); request.setCharacterEncoding("utf-8"); //取得上传文件,读取文件 Part part = request.getPart("file1"); //定义一个变量去接收文件名 String filename = null; //Content-Disposition: 就是当用户想把请求所得的内容存为一个文件的时候提供一个默认的文件名 //Content-Disposition:告诉浏览器以下载的方式打开文件 for (String content : part.getHeader("content-disposition").split(";")) { System.out.println(content); //取得文件名 if (content.trim().startsWith("filename")) { //截取文件名 filename = content.substring( content.indexOf('=') + 1).trim().replace("\"", ""); } } //输出流 OutputStream out = null; //输入流 InputStream filecontent = null; //File.separator 取得系统的分割线等数据 out = new FileOutputStream(new File("e:/loads" + File.separator + filename)); int read; //获得一个输入流 filecontent = part.getInputStream(); final byte[] bytes = new byte[1024]; while ((read = filecontent.read(bytes)) != -1) { out.write(bytes, 0, read); } System.out.println("New file " + filename + " created at " + "/loads"); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } }
(第三种上传的方法)
这里使用的是jspSmartUpload包上传下载,笔者认为这种上传下载较为简单,但是好像不是很多人用,不懂,下载地址在这里(点我下载)
创建HTML页面
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>上传文件</title> </head> <body> <p> </p> <p align="center">上传文件选择</p> <form method="post" Action="../DouploadServlet" enctype="multipart/form-data"> <table width="75%" border="1" align="center"> <tr><td><div align="center"> 1.<input type="file" name="file1" > </div></td></tr> <tr><td><div align="center"> 2.<input type="file" name="file2" > </div></td></tr> <tr><td><div align="center"> 3.<input type="file" name="file3" > </div></td></tr> <tr><td><div align="center"> <input type="submit" name="Submit" value="上传他"> </div></td></tr> </table> </form> </body> </html>
创建Servlet处理上传文件
package com.load; import java.io.IOException; import java.io.PrintWriter; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.jsp.JspFactory; import javax.servlet.jsp.PageContext; import com.jspsmart.upload.File; import com.jspsmart.upload.SmartUpload; import com.jspsmart.upload.SmartUploadException; @WebServlet("/DouploadServlet") public class DouploadServlet extends HttpServlet { private static final long serialVersionUID = 1L; public DouploadServlet() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/html;charset=UTF-8"); PrintWriter out = response.getWriter(); //新建一个智能上传对象 SmartUpload su = new SmartUpload(); /* * PageContext pageContext; HttpSession session; ServletContext application; ServletConfig config; JspWriter out; Object page = this; HttpServletRequest request, HttpServletResponse response 其中page对象,request和response已经完成了实例化,而其它5个没有实例化的对象通过下面的方式实例化 pageContext = jspxFactory.getPageContext(this, request, response,null, true, 8192, true); */ //通过Jsp工厂类获取上下文环境 PageContext pagecontext = JspFactory.getDefaultFactory().getPageContext(this, request, response, null, true, 8192, true); //上传初始化 su.initialize(pagecontext); //上传文件 try { su.upload(); //将上传文件保存到指定目录 int count = su.save("/share"); out.println(count+"个文件上传成功!<br>"+su.toString()); } catch (SmartUploadException e) { e.printStackTrace(); } //逐个提取上传文件信息 for(int i=0;i<su.getFiles().getCount();i++){ File file = su.getFiles().getFile(i); //如果文件不存在 if(file.isMissing()) continue; //显示当前文件信息 out.println("<table border=1>"); out.println("<tr><td>表单项名(FieldName)</td></td>"+file.getFieldName()+"</td></tr>"); out.println("<tr><td>文件长度</td><td>"+file.getSize()+"</td></tr>"); out.println("<tr><td>文件名</td><td>"+file.getFileName()+"</td></tr>"); out.println("<tr><td>文件扩展名</td><td>"+file.getFileExt()+"</td></tr>"); out.println("<tr><td>文件全名</td><td>"+file.getFilePathName()+"</td></tr>"); out.println("</table><br>"); } } /** * @see HttpServlet#doPost(HttpServletRequest request, HttpServletResponse response) */ protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { // TODO Auto-generated method stub doGet(request, response); } }
注意:代码
int count = su.save("/share");表示你需要先建个文件夹,所以你可以先在Webcontent建立一个,然后将项目取消部署,再重新部署进去之后就会在运行那边建立起一个文件夹了!
或者你可以直接找到运行的路径,然后建立share文件夹。
3、实现文件下载
(第一种文件下载)
注意:该代码是直接访问Servlet类的
package com.load; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; //直接使用Http://localhost:8080/Test1/download进行下载,但是这个有缺陷,如果下载文件名中有中文,就会变成乱码现象! @WebServlet("/download") public class download extends HttpServlet { private static final long serialVersionUID = 1L; public download() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { response.setContentType("text/plain;charset=utf-8"); response.setCharacterEncoding("utf-8"); response.setHeader("Location","中文.txt"); response.setHeader("Content-Disposition", "attachment; filename=" + "账号.txt"); OutputStream outputStream = response.getOutputStream(); InputStream inputStream = new FileInputStream("E:/loads"+"/账号.txt"); byte[] buffer = new byte[1024]; int i = -1; while ((i = inputStream.read(buffer)) != -1) { outputStream.write(buffer, 0, i); } outputStream.flush(); outputStream.close(); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
(第二种下载方法)
新建jsp页面选择下载
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%> <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> <title>下载</title> </head> <body> <a href="../DoDownloadServlet?filename=呵呵.txt">点击下载</a> </body> </html>
创建Servlet类进行下载(注意:该下载如果文件名是中文的话,一样会出现乱码现象)
package com.load; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URLEncoder; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.jsp.JspFactory; import javax.servlet.jsp.PageContext; import org.hsqldb.lib.StringUtil; import com.jspsmart.upload.SmartUpload; import com.jspsmart.upload.SmartUploadException; @WebServlet("/DoDownloadServlet") public class DoDownloadServlet extends HttpServlet { private static final long serialVersionUID = 1L; public DoDownloadServlet() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //得到下载文件的名称 //String filename = request.getParameter("filename"); //String filename = new String(FileName.getBytes("iso8859-1"),"UTF-8"); //新建SmartUpload对象 SmartUpload su = new SmartUpload(); PageContext pagecontext = JspFactory.getDefaultFactory().getPageContext(this, request, response, null, true, 8192, true); //上传初始化 su.initialize(pagecontext); //设置禁止打开该文件 su.setContentDisposition(null); //下载文件 try { su.downloadFile("/listener/"+filename); } catch (SmartUploadException e) { // TODO Auto-generated catch block e.printStackTrace(); } } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
(第三种下载的方法)
同上的jsp页面代码,这里就不再重复了。
新建Serlvet类,实现下载功能(注意:这里文件名就算是中文名,也不会出现乱码问题了!)
package com.load; import java.io.BufferedInputStream; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.URLEncoder; import javax.servlet.ServletException; import javax.servlet.annotation.WebServlet; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.jsp.JspFactory; import javax.servlet.jsp.PageContext; import org.hsqldb.lib.StringUtil; import com.jspsmart.upload.SmartUpload; import com.jspsmart.upload.SmartUploadException; @WebServlet("/DoDownloadServlet") public class DoDownloadServlet extends HttpServlet { private static final long serialVersionUID = 1L; public DoDownloadServlet() { super(); } protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { //获得文件名称 String path1 = request.getParameter("filename"); //获得路径名称 String path = request.getSession().getServletContext().getRealPath("/listener/"+path1); // path是根据日志路径和文件名拼接出来的 File file = new File(path); String filename = file.getName(); try { //判断是否是IE11 Boolean flag= request.getHeader("User-Agent").indexOf("like Gecko")>0; //IE11 User-Agent字符串:Mozilla/5.0 (Windows NT 6.1; WOW64; Trident/7.0; rv:11.0) like Gecko //IE6~IE10版本的User-Agent字符串:Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.0; Trident/6.0) if (request.getHeader("User-Agent").toLowerCase().indexOf("msie") >0||flag){ filename = URLEncoder.encode(filename, "UTF-8");//IE浏览器 }else { //先去掉文件名称中的空格,然后转换编码格式为utf-8,保证不出现乱码, //这个文件名称用于浏览器的下载框中自动显示的文件名 filename = new String(filename.replaceAll(" ", "").getBytes("UTF-8"), "ISO8859-1"); //firefox浏览器 //firefox浏览器User-Agent字符串: //Mozilla/5.0 (Windows NT 6.1; WOW64; rv:36.0) Gecko/20100101 Firefox/36.0 } InputStream fis = new BufferedInputStream(new FileInputStream(path)); byte[] buffer; buffer = new byte[fis.available()]; fis.read(buffer); fis.close(); response.reset(); response.addHeader("Content-Disposition", "attachment;filename=" +filename); response.addHeader("Content-Length", "" + file.length()); OutputStream os = response.getOutputStream(); response.setContentType("application/octet-stream"); os.write(buffer);// 输出文件 os.flush(); os.close(); } catch (IOException e) { e.printStackTrace(); } System.out.println(filename); } protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { doGet(request, response); } }
基本就是这样,有问题的话请下方评论,谢谢