javaWeb文件上传与下载
文件上传与下载在项目中运用的使用频率很大 今天也花时间整理了一下 多文件上传图片回显 和文件下载
1.多文件上传
这里会涉及到几个属性
fileSizeThreshold:缓冲区文件的大小 如果上传的文件的超过了缓冲区的值 那么就会生成一个临时文件存放到指定目录中 缓冲区的大小默认是10KB
maxFileSize:单个文件上传的大小
maxRequestSize :总共上传文件的最大值
location:文件上传的位置
注意一点当我们上传了多个文件名相同的文件时 上传的文件会覆盖掉前面上传的文件 但是可能只是文件名相同文件的内容不同 这时该怎么办呢?
这里提供了两种方法
第一种方法 我们可以在输出流中添加系统时间 以为每次我上传文件的时候时间是不同的
第二种方法
还可以使用java中提供的UUID通用唯一识别码 UUID是唯一的
String uuid = UUID.randomUUID().toString();
1package com.newroad.upload; 2 import java.io.File; 3 import java.io.FileInputStream; 4 import java.io.FileOutputStream; 5 import java.io.IOException; 6 import java.io.InputStream; 7 import java.io.PrintWriter; 8 import java.util.Collection; 9 import java.util.UUID; 10 import javax.servlet.ServletException; 11 import javax.servlet.annotation.MultipartConfig; 12 import javax.servlet.annotation.WebServlet; 13 import javax.servlet.http.HttpServlet; 14 import javax.servlet.http.HttpServletRequest; 15 import javax.servlet.http.HttpServletResponse; 16 import javax.servlet.http.Part; 17 @WebServlet("/upload02.do") 18 @MultipartConfig 19 /*@MultipartConfig(fileSizeThreshold=1024*50,location="d:/test1",maxFileSize=1024*1024,maxRequestSize=1024*1024)*/ 20 @SuppressWarnings("serial") 21 public class UpLoadServlet2 extends HttpServlet{ 22 23 @Override 24 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { 25 //获得所有的前台传递的数据部分,包含文件,包含文本 26 Collection<Part> parts = request.getParts(); 27 //遍历集合 28 for(Part part : parts) { 29 if(!part.getName().equals("file")) { 30 continue ; 31 } 32 //获得这个文件的名称 33 String fileName = part.getSubmittedFileName(); 34 //将文件保存到指定的位置 我们约定的位置在 webapp/upload/ch10_01 35 String realpath = request.getServletContext().getRealPath(""); 36 //获得webapp的真实路径 37 File webappPath = new File(realpath).getParentFile(); 38 //获得约定的路径的File对象 39 File uploadDi = new File(webappPath,"upload"+request.getContextPath()); 40 //为了避免首次上传,文件夹找不到 创建文件夹 41 uploadDi.mkdirs(); 42 //创建UUID 43 String uuid = UUID.randomUUID().toString(); 44 System.out.println(uuid); 45 FileOutputStream out = new FileOutputStream(new File(uploadDi,System.currentTimeMillis()+"_"+fileName)); 46 //获取输入流 47 InputStream in = part.getInputStream(); 48 //创建缓冲区 49 byte[] b = new byte[1024]; 50 int num=0 ; 51 //循环将输入流中的数据读到缓冲区中 52 while((num=in.read(b))!=-1) { 53 out.write(b, 0, num); 54 } 55 in.close(); 56 out.close(); 57 } 58 //响应上传结果 59 response.setCharacterEncoding("utf-8"); 60 response.setContentType("text/html;charset=utf-8"); 61 62 PrintWriter writer = response.getWriter(); 63 writer.write("上传成功"); 64 writer.close(); 65 66 67 } 68 69 @Override 70 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { 71 doGet(req, resp); 72 } 73 }
2.图片上传以及回显
经常我们会看到当我们在qq或者其他软件中上传图片的时候 就会把上传的图片显示出来 接下来来实现这个功能
注意以下
contentType : false 必须是false,才能够被设置正确的内容类型
processData : false 告诉jquery不要对数据做处理,如果不设置,那么jquery会按照它的规则对数据进行处理
1 <%@ page language="java" contentType="text/html; charset=UTF-8" 2 pageEncoding="UTF-8"%> 3 <% 4 String basePath = request.getScheme() + "://" + request.getServerName() + ":" + request.getServerPort() 5 + request.getContextPath() + "/"; 6 %> 7 <!DOCTYPE html> 8 <html> 9 <head> 10 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> 11 <base href="<%=basePath%>"> 12 <title>使用ajax上传图片后,回显至页面</title> 13 <script type="text/javascript" src="js/jquery.js"></script> 14 <script type="text/javascript"> 15 $(function() { 16 $("input[type=submit]").on("click", function() { 17 //阻滞默认提交时间 18 event.preventDefault(); 19 //数据需要使用到FormData这个对象,将表单中的数据封装到FormData对象中 20 //获得表单对象,不能使用jquery的方式,必须使用原生js来获取 21 var form = document.getElementById("p1"); 22 var formData = new FormData(form); 23 $.ajax({ 24 url : "upload03.do", 25 data : formData, 26 type : "POST", 27 //必须是false,才能够被设置正确的内容类型 28 contentType : false, 29 //告诉jquery不要对数据做处理,如果不设置,那么jquery会按照它的规则对数据进行处理 30 processData : false, 31 //设置上传成功之后 回显图片 32 success : function(data) { 33 if (data.path) { 34 $("#p1").css("display", "inline"); 35 $("#p1").attr("src", "../" + data.path); 36 } 37 38 } 39 40 }) 41 42 }) 43 44 }) 45 </script> 46 <style type="text/css"> 47 #p1 { 48 width: 200px; 49 display: none; 50 height: 200px; 51 } 52 </style> 53 </head> 54 <body> 55 <form id="ff"> 56 <input type="file" name="file" accept="image/jpeg,image/png,image/gif"><br> 57 <input type="submit" value="准备上传">
<img id="p1"> 58 </form> 59 </body> 60 </html>
图片上传回显其实就是将 图片上传成功后将拿到图片的地址 然后 通过ajax拿到图片的地址 并设置图片的显示方式
1 package com.newroad.upload;
2 import java.io.File;
3 import java.io.FileOutputStream;
4 import java.io.IOException;
5 import java.io.InputStream;
6 import java.io.PrintWriter;
7 import javax.servlet.ServletException;
8 import javax.servlet.annotation.MultipartConfig;
9 import javax.servlet.annotation.WebServlet;
10 import javax.servlet.http.HttpServlet;
11 import javax.servlet.http.HttpServletRequest;
12 import javax.servlet.http.HttpServletResponse;
13 import javax.servlet.http.Part;
14
15 import com.alibaba.fastjson.JSONObject;
16
17 @WebServlet("/upload03.do")
18 @MultipartConfig
19 @SuppressWarnings("serial")
20 public class UpLoadServlet3 extends HttpServlet {
21
22 @Override
23 protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
24 //获取上传的文件 通过input标签中的name属性值获得相应的Part对象
25 Part part = request.getPart("file");
26 //获取文件名称
27 String fileName =part.getSubmittedFileName();
28 //获得tomcat的目录
29 String realPath =request.getServletContext().getRealPath("");
30 File parentFile = new File(realPath).getParentFile();
31 File uploadDi = new File(parentFile,"upload"+request.getContextPath());
32 //创建文件夹
33 uploadDi.mkdirs();
34 //将文件写出到硬盘中
35 FileOutputStream out = new FileOutputStream(new File(uploadDi,fileName));
36 //获得输入流
37 InputStream in = part.getInputStream();
38 //创建一个缓冲区
39 byte[] b = new byte[1024*3];
40 //判断输入流中的数据读完的标志
41 int num = 0 ;
42 //循环将输入流中的数据读取到缓冲区中 判断读完的标志是num=in.read(b)>0
43 while((num=in.read(b)) !=-1) {
44 //将缓冲区的数据写到指定的目录中
45 out.write(b, 0, num);
46 }
out.close();
48 in.close();
49
50 //响应信息
51 response.setCharacterEncoding("utf-8");
52 response.setContentType("application/json;charset=utf-8");
53 PrintWriter writer = response.getWriter();
54 //将图片地址响应给前端
55 String path = "upload"+request.getContextPath()+"/"+fileName ;
56 JSONObject jobj = new JSONObject();
57 jobj.put("path", path);
58
59 writer.write(jobj.toJSONString());
60 writer.close();
61 }
62
63 @Override
64 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
65 doGet(req, resp);
66 }
67
68 }
3.文件下载
1 <%@ page language="java" contentType="text/html; charset=UTF-8"
2 pageEncoding="UTF-8"%>
3 <%
4 String basePath=request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/";
5 %>
6 <!DOCTYPE html>
7 <html>
8 <head>
9 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
10 <base href="<%=basePath%>">
11 <title>下载文件</title>
12 </head>
13 <body>
14 <h2>文本文档</h2><a href="download.do?file=端口号别站用.txt">端口号别站用</a>
15 <h2>学习视频</h2><a href="download.do?file=用户角色权限.wmv">用户角色权限</a>
16
17 </body>
18 </html>
DownLoadServlet
注意
当我们下载一个中文名的文件的时候可能会出现乱码 这时需要设置响应头的信息
Content-Disposition 响应头的格式为 inline|attachment;filename=文件名
inline表示如果该资源浏览器能够直接展示,则直接展示,否则下载,attachment表示直接以附件形式下载
如果文件有中文名 这时可以使用URLEncoder.encode方法,将文件名编码成unicode码
1 package com.newroad.upload;
2 import java.io.File;
3 import java.io.FileInputStream;
4 import java.io.IOException;
5 import java.io.OutputStream;
6 import java.io.PrintWriter;
7 import java.net.URLEncoder;
8 import javax.servlet.ServletException;
9 import javax.servlet.annotation.WebServlet;
10 import javax.servlet.http.HttpServlet;
11 import javax.servlet.http.HttpServletRequest;
12 import javax.servlet.http.HttpServletResponse;
13 @WebServlet("/download.do")
14 @SuppressWarnings("serial")
15 public class DownLoadServlet extends HttpServlet {
16 @Override
17 protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
18 req.setCharacterEncoding("utf-8");
19 resp.setCharacterEncoding("utf-8");
20 // 获得到参数中的下载文件的名字
21 String filename = req.getParameter("file");
22 System.out.println(filename);
23 File file = new File("D:/" + filename);
24 if (file.exists()) {
25 /*
26 * 设置响应头信息,Content-Disposition 响应头的格式为 inline|attachment;filename=文件名
27 * inline表示如果该资源浏览器能够直接展示,则直接展示,否则下载,attachment表示直接以附件形式下载
28 * 如果文件名中有中文,那么下载时,会出现中文乱码,这时可以使用URLEncoder.encode方法,将文件名编码成unicode码
29 */
30 String contentDisposition = "attachment;filename=" + URLEncoder.encode(file.getName(), "utf-8");
31 resp.setHeader("Content-Disposition", contentDisposition);
32 // 创建文件字节读取流对象时,必须明确与之关联的数据源。
33 FileInputStream in = new FileInputStream(file);
34 // 获取输出流
35 OutputStream oStream = resp.getOutputStream();
36 // 创建缓冲区
37 byte[] b = new byte[1024 * 3];
38 // number用来判断输入流读完的标记
39 int number;
40 // 循环读取输入流中的数据到缓冲区中
41 while ((number = in.read(b)) != -1) {
42 oStream.write(b, 0, number);
43 }
44 oStream.close();
45 in.close();
46 } else {
47 resp.setContentType("text/html;charset=utf-8");
48 PrintWriter writer = resp.getWriter();
49 writer.write("该文件丢失了");
50 writer.close();
51 }
52
53 }
54
55 @Override
56 protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
57
58 doGet(req, resp);
59 }
60 }