文件上传和下载(可批量上传)——Spring(三)

文件上传和下载(可批量上传)——Spring(二)的基础上,发现了文件下载时,只有在Chrome浏览器下文件名正常显示,还有发布到服务器后,不能上传到指定的文件夹目录,如上传20160310.txt文件,上传到正是服务器后,并没有在upload文件夹下,而是以upload/20160310.txt这样的文加名的文件。针对以上问题,进行了修正。最后一个错误是,在显示文件列表的时候如果对应项目下没有文件夹会报空指针异常。

处理空指针异常的。

处理文件名中文显示正常和处理无法上传到正确的文件夹

完整代码如下

  1 package com.tommy.business;
  2 
  3 import org.apache.commons.fileupload.FileItem;
  4 import org.apache.commons.fileupload.FileUploadException;
  5 import org.apache.commons.fileupload.disk.DiskFileItemFactory;
  6 import org.apache.commons.fileupload.servlet.ServletFileUpload;
  7 import org.springframework.stereotype.Controller;
  8 import org.springframework.web.bind.annotation.RequestMapping;
  9 import org.springframework.web.multipart.MultipartFile;
 10 import org.springframework.web.multipart.MultipartHttpServletRequest;
 11 import org.springframework.web.multipart.commons.CommonsMultipartFile;
 12 import org.springframework.web.multipart.commons.CommonsMultipartResolver;
 13 
 14 import javax.servlet.ServletException;
 15 import javax.servlet.http.HttpServletRequest;
 16 import javax.servlet.http.HttpServletResponse;
 17 import java.io.*;
 18 import java.net.URLEncoder;
 19 import java.util.HashMap;
 20 import java.util.List;
 21 import java.util.Map;
 22 
 23 /**
 24  * Created by OnlyOne on 2016/3/4.
 25  */
 26 @Controller
 27 @RequestMapping("/background/uploadAndDownload/")
 28 public class UploadAndDownloadController {
 29     /**
 30      *
 31      * @param req
 32      * @param resp
 33      * @throws ServletException
 34      * @throws IOException
 35      * @throws FileUploadException
 36      */
 37     @RequestMapping("uploadFile")
 38     public String uploadFile(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException, FileUploadException {
 39         /*//防止中文乱码,与页面字符集一致
 40         req.setCharacterEncoding("UTF-8");*/
 41         //得到上传文件的保存目录,将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全
 42         String savePath = req.getServletContext().getRealPath("/upload");
 43 //                            this.getServletContext().getRealPath("/WEB-INF/upload");
 44         //创建保存目录的文件
 45         File saveFile = new File(savePath);
 46         //判断保存目录文件是否存在,不存在则创建一个文件夹
 47         if(!saveFile.exists()){
 48             System.out.println("文件目录创建中。。。");
 49             saveFile.mkdir();
 50         }
 51         //消息提示
 52         //将req转换成Spring的request
 53         MultipartHttpServletRequest multipartHttpServletRequest = (MultipartHttpServletRequest) req;
 54         //获取上传文件
 55         List<MultipartFile> list = multipartHttpServletRequest.getFiles("file");
 56         /*//获取普通输入项的数据
 57         String map = multipartHttpServletRequest.getParameter("username");
 58         System.out.println(map);*/
 59         for(MultipartFile multipartFile: list){
 60             if(!multipartFile.isEmpty()){
 61                 //得到上传的文件名称
 62                 String fileName = multipartFile.getOriginalFilename();
 63                 System.out.println("文件名是:"+ fileName);
 64                 if(fileName == null || fileName.trim().equals("")){
 65                     continue;
 66                 }
 67                 //获取item中的上传输入流
 68                 BufferedInputStream bis = new BufferedInputStream(multipartFile.getInputStream());
 69                 //创建一个文件输出流
 70                 BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(savePath + "/" + fileName));
 71                 //创建一个缓冲区
 72                 byte[] buffer = new byte[1024*8];
 73                 //循环将缓冲输入流读入到缓冲区当中
 74                 while(true){
 75                     //循环将缓冲输入流读入到缓冲区当中
 76                     int length = bis.read(buffer);
 77                     //判断是否读取到文件末尾
 78                     if(length == -1){
 79                         break;
 80                     }
 81                     //使用BufferedOutputStream缓冲输出流将缓冲区的数据写入到指定的目录(savePath + "\\" + filename)当中
 82                     bos.write(buffer,0,length);
 83                 }
 84                 //关闭输入流
 85                 bis.close();
 86                 //关闭输出流
 87                 bos.close();
 88             }
 89         }
 90             return "redirect:listFile.html";
 91     }
 92 
 93     /**
 94      * @ClassName: ListFileServlet
 95      * @Description: 列出Web系统中所有下载文件
 96      * @param req
 97      * @param resp
 98      */
 99     @RequestMapping("listFile")
100     public String listFile(HttpServletRequest req, HttpServletResponse resp) {
101         String flag = req.getParameter("flag");
102         //获取上传文件的目录
103         String uploadFilePath = req.getServletContext().getRealPath("/upload");
104         //创建保存目录的文件
105         File saveFile = new File(uploadFilePath);
106         //判断保存目录文件是否存在,不存在则创建一个文件夹
107         if(!saveFile.exists()){
108             System.out.println("文件目录创建中。。。");
109             saveFile.mkdir();
110         }
111         //存储要下载的文件名
112         Map<String, String> fileNameMap = new HashMap<String, String>();
113         //地鬼遍历filePath目录下的所有文件和目录,将文件的文件名存储到map集合中
114         getListfile(new File(uploadFilePath), fileNameMap);
115         if(flag != null){
116             req.setAttribute("flag",flag);
117         }
118         req.setAttribute("fileNameMap", fileNameMap);
119         return "/background/uploadAndDownload/resourcesList";
120     }
121 
122     /**
123      *
124      * @param file 即代表一个文件,也代表一个文件目录
125      * @param map  存储文件名的Map集合
126      * @Method: listfile
127      * @Description: 递归遍历指定目录下的所有文件
128      */
129     private void getListfile(File file, Map<String, String> map) {
130         //如果file代表的不是一个文件,而是一个目录
131         if (!file.isFile()) {
132             //列出该目录下的所有文件和目录
133             File files[] = file.listFiles();
134             //遍历files[]数组
135             for (File f : files) {
136                 //递归
137                 getListfile(f, map);
138             }
139         } else {
140             /**
141              * 处理文件名,上传后的文件是以uuid_文件名的形式去重新命名的,去除文件名的uuid_部分
142              file.getName().indexOf("_")检索字符串中第一次出现"_"字符的位置,如果文件名类似于:9349249849-88343-8344_阿_凡_达.avi
143              那么file.getName().substring(file.getName().indexOf("_")+1)处理之后就可以得到阿_凡_达.avi部分
144              */
145             //String realName = file.getName().substring(file.getName().indexOf("_") + 1);
146             //file.getName()得到的是文件的原始名称,这个名称是唯一的,因此可以作为key,realName是处理过后的名称,有可能会重复
147             map.put(file.getName(), file.getName());
148         }
149     }
150 
151     /**
152      * 下载文件
153      * @param req
154      * @param resp
155      * @throws ServletException
156      * @throws IOException
157      */
158     @RequestMapping("downLoadFile")
159     public void downLoadFile(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
160         /*//得到要下载的文件名
161         req.setCharacterEncoding("UTF-8");*/
162         String fileName = req.getParameter("fileName");
163 //        fileName = new String(fileName.getBytes("iso8859-1"),"UTF-8");
164         //上传的文件都是保存在/WEN-INF/upload目录党徽宗
165         String fileSavePath = req.getServletContext().getRealPath("/upload");
166         //得到要下载的文件
167         File file = new File(fileSavePath + "//" + fileName);
168         //如果文件不存在
169         if(!file.exists()){
170             req.setAttribute("message", "资源已被删除!");
171             req.getRequestDispatcher("/message.jsp").forward(req, resp);
172         }
173         //处理文件名
174         String realName = fileName.substring(fileName.indexOf("_")+1);
175         String agent = req.getHeader("user-agent");
176         resp.setContentType("application/x-download");
177         //处理下载时文件名乱码,针对不同浏览器做处理
178         if(agent.contains("Firefox")){
179             realName = new String(realName.getBytes("GB2312"),"ISO-8859-1");
180             //resp.addHeader("Content-Disposition","attachment;filename="+ new String(realName.getBytes("GB2312"),"ISO-8859-1"));
181         }else {
182             realName = URLEncoder.encode(realName, "UTF-8");
183             //resp.addHeader("Content-Disposition","attachment;filename=" + URLEncoder.encode(realName, "UTF-8"));
184         }
185         //设置响应头,控制浏览器下载该文件
186         resp.setHeader("content-disposition", "attachment;filename="+realName);
187         //读取要下载的文件,保存到文件输入流
188         BufferedInputStream bis = new BufferedInputStream(new FileInputStream(fileSavePath + "/" + fileName));
189         //以前的写法,本地可以,发布到服务器后就不能上传到指定的文件夹而是已upload\***的形式作为文件名,应该是转义符"\\"在linux转义的不是"/"
190         // BufferedInputStream bis = new BufferedInputStream(new FileInputStream(fileSavePath + "\\" + fileName));
191         //创建输出流
192         BufferedOutputStream bos = new BufferedOutputStream(resp.getOutputStream());
193         //创建一个缓冲区
194         byte[] buffer = new byte[1024*8];
195         //循环将缓冲输入流读入到缓冲区当中
196         while(true){
197             //循环将缓冲输入流读入到缓冲区当中
198             int length = bis.read(buffer);
199             //判断是否读取到文件末尾
200             if(length == -1){
201                 break;
202             }
203             //使用BufferedOutputStream缓冲输出流将缓冲区的数据写入到指定的目录(savePath + "\\" + filename)当中
204             bos.write(buffer,0,length);
205         }
206         //关闭文件输入流
207         bis.close();
208         //刷新此输入流并强制写出所有缓冲的输出字节数
209         bos.flush();
210         //关闭文件输出流
211         bos.close();
212     }
213 
214 }

 

posted @ 2016-03-10 10:53  路途寻码人  阅读(573)  评论(0编辑  收藏  举报