zoukankan      html  css  js  c++  java
  • 文件上传和下载

    FileUploadController:

    package com.activiti.web;
    
    import java.util.List;
    import java.util.Map;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestBody;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.ResponseBody;
    import org.springframework.web.multipart.MultipartFile;
    import org.springframework.web.multipart.MultipartHttpServletRequest;
    
    import com.activiti.service.FileService;
    import com.cinms.common.ResultModel;
    /**
     * @author Jump
     * @version 创建时间:2018年6月20日 下午4:47:37 
     * 文件上传控制器
     */
    @Controller
    public class FileUploadController {
        @Autowired
        private FileService fileService;
    
        private Logger logger = LoggerFactory.getLogger(FileUploadController.class);
        
        @RequestMapping("upload")
        @ResponseBody
        public ResultModel upload(
                HttpServletRequest request) {
             MultipartHttpServletRequest multipartRequest = (MultipartHttpServletRequest) request;
            List<MultipartFile> files = multipartRequest.getFiles("file");
            //MultipartFile[] files = (MultipartFile[])request.getAttribute("file");
            ResultModel rm = fileService.upload(files, request);
            return rm;
        }
        
        @RequestMapping("download")
        @ResponseBody
        public void download(@RequestBody Map<String, String> map,
                HttpServletResponse response,HttpServletRequest request) {
            try {
                String fileName = map.get("fileName");
                fileService.download(fileName,response,request);
            } catch (Exception e) {
                e.printStackTrace();
                logger.error("文件上传失败:"+ e);
            }
        }
    }

    FileServiceImpl:

    package com.activiti.serviceImpl;
    
    import org.springframework.stereotype.Service;
    
    import com.activiti.service.FileService;
    import com.activiti.tools.PropertiesUtil;
    import com.cinms.common.ResultModel;
    import com.google.common.collect.Lists;
    
    import org.apache.commons.fileupload.ProgressListener;
    import org.apache.commons.fileupload.disk.DiskFileItemFactory;
    import org.apache.commons.fileupload.servlet.ServletFileUpload;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.web.multipart.MultipartFile;
    
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileOutputStream;
    import java.io.InputStream;
    import java.io.OutputStream;
    import java.net.URLEncoder;
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.UUID;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    /**
     * @author Jump
     * @version 创建时间:2018年6月20日 上午10:22:40 类说明
     */
    @Service("iFileService")
    public class FileServiceImpl implements FileService {
    
        private Logger logger = LoggerFactory.getLogger(FileServiceImpl.class);
    
        @Override
        public ResultModel upload(List<MultipartFile> files, HttpServletRequest request) {
            ResultModel rm = new ResultModel();
            // 得到上传文件的保存目录,将上传的文件存放于WEB-INF目录下,不允许外界直接访问,保证上传文件的安全
            //String savePath = request.getSession().getServletContext().getRealPath("/WEB-INF/upload");
            //String savePath = PropertiesUtil.getProperty("FILELOCATION");
            String savePath = "./upload";
            // 上传时生成的临时文件保存目录
            String tempPath = request.getSession().getServletContext().getRealPath("/WEB-INF/temp");
            File tmpFile = new File(tempPath);
            if (!tmpFile.exists()) {
                // 创建临时目录
                tmpFile.mkdir();
            }
    
            try {
                // 使用Apache文件上传组件处理文件上传步骤:
                // 1、创建一个DiskFileItemFactory工厂
                DiskFileItemFactory factory = new DiskFileItemFactory();
                // 设置工厂的缓冲区的大小,当上传的文件大小超过缓冲区的大小时,就会生成一个临时文件存放到指定的临时目录当中。
                factory.setSizeThreshold(1024 * 100);// 设置缓冲区的大小为100KB,如果不指定,那么缓冲区的大小默认是10KB
                // 设置上传时生成的临时文件的保存目录
                factory.setRepository(tmpFile);
                // 2、创建一个文件上传解析器
                ServletFileUpload upload = new ServletFileUpload(factory);
                // 监听文件上传进度
                upload.setProgressListener(new ProgressListener() {
                    @Override
                    public void update(long pBytesRead, long pContentLength, int arg2) {
                        System.out.println("文件大小为:" + pContentLength + ",当前已处理:" + pBytesRead);
                        /**
                         * 文件大小为:14608,当前已处理:4096 文件大小为:14608,当前已处理:7367
                         * 文件大小为:14608,当前已处理:11419 文件大小为:14608,当前已处理:14608
                         */
                    }
                });
                // 解决上传文件名的中文乱码
                upload.setHeaderEncoding("UTF-8");
                // 3、判断提交上来的数据是否是上传表单的数据
                if (!ServletFileUpload.isMultipartContent(request)) {
                    // 按照传统方式获取数据
                    return null;
                }
    
                // 设置上传单个文件的大小的最大值,目前是设置为1024*1024字节,也就是1MB
                upload.setFileSizeMax(1024 * 1024);
                // 设置上传文件总量的最大值,最大值=同时上传的多个文件的大小的最大值的和,目前设置为10MB
                upload.setSizeMax(1024 * 1024 * 10);
                /*
                 * // 4、使用ServletFileUpload解析器解析上传数据,解析结果返回的是一个List<FileItem>集合,
                 * 每一个FileItem对应一个Form表单的输入项 List<FileItem> list =
                 * upload.parseRequest(request);
                 */
                String filenames = "";
                HashMap<String, String> hm = new HashMap<String, String>();
                ArrayList<HashMap<String, String>> arrayList = Lists.newArrayList();
                for (MultipartFile item : files) {
                    // 如果fileitem中封装的是上传文件
                    // 得到上传的文件名称,
                    String filename = item.getOriginalFilename();
                    System.out.println(filename);
                    if (filename == null || filename.trim().equals("")) {
                        continue;
                    }
                    // 注意:不同的浏览器提交的文件名是不一样的,有些浏览器提交上来的文件名是带有路径的,如:
                    // c:a1.txt,而有些只是单纯的文件名,如:1.txt
                    // 处理获取到的上传文件的文件名的路径部分,只保留文件名部分
                    filename = filename.substring(filename.lastIndexOf("\") + 1);
                    // 得到上传文件的扩展名
                    String fileExtName = filename.substring(filename.lastIndexOf(".") + 1);
                    // 如果需要限制上传的文件类型,那么可以通过文件的扩展名来判断上传的文件类型是否合法
                    System.out.println("上传的文件的扩展名是:" + fileExtName);
                    // 获取item中的上传文件的输入流
                    InputStream in = item.getInputStream();
                    // 得到文件保存的名称
                    String saveFilename = makeFileName(filename);
                    // 得到文件的保存目录
                    String realSavePath = makePath(saveFilename, savePath);
                    // 创建一个文件输出流
                    FileOutputStream out = new FileOutputStream(realSavePath + "\" + saveFilename);
                    // 创建一个缓冲区
                    byte buffer[] = new byte[1024];
                    // 判断输入流中的数据是否已经读完的标识
                    int len = 0;
                    // 循环将输入流读入到缓冲区当中,(len=in.read(buffer))>0就表示in里面还有数据
                    while ((len = in.read(buffer)) > 0) {
                        // 使用FileOutputStream输出流将缓冲区的数据写入到指定的目录(savePath + "\"
                        // + filename)当中
                        out.write(buffer, 0, len);
                    }
                    // 关闭输入流
                    in.close();
                    // 关闭输出流
                    out.close();
                    filenames = realSavePath + "\" + saveFilename;
                    hm.put("name", filename);
                    hm.put("path", filenames);
                    arrayList.add(hm);
                }
                rm.setData(arrayList);
                rm.setMessage("文件上传成功!");
                rm.setSuccess(true);
            } catch (Exception e) {
                e.printStackTrace();
                rm.setMessage("文件上传失败!");
                rm.setSuccess(false);
                logger.error("文件上传失败!");
            }
            return rm;
        }
    
        /**
         * 为防止一个目录下面出现太多文件,要使用hash算法打散存储
         * 
         * @Method: makePath
         * @Description:
         *
         * @param filename
         *            文件名,要根据文件名生成存储目录
         * @param savePath
         *            文件存储路径
         * @return 新的存储目录
         */
        private String makePath(String filename, String savePath) {
            // 得到文件名的hashCode的值,得到的就是filename这个字符串对象在内存中的地址
            int hashcode = filename.hashCode();
            int dir1 = hashcode & 0xf; // 0--15
            int dir2 = (hashcode & 0xf0) >> 4; // 0-15
            // 构造新的保存目录
            String dir = savePath + "\" + dir1 + "\" + dir2; // upload23
                                                                // upload35
            // File既可以代表文件也可以代表目录
            File file = new File(dir);
            // 如果目录不存在
            if (!file.exists()) {
                // 创建目录
                file.mkdirs();
            }
            return dir;
        }
    
        /**
         * @Method: makeFileName
         * @Description: 生成上传文件的文件名,文件名以:uuid+"_"+文件的原始名称
         * @param filename
         *            文件的原始名称
         * @return uuid+"_"+文件的原始名称
         */
        private String makeFileName(String filename) { // 2.jpg
            // 为防止文件覆盖的现象发生,要为上传文件产生一个唯一的文件名
            return UUID.randomUUID().toString() + "_" + filename;
        }
    
        @Override
        public void download(String fileName, HttpServletResponse response, HttpServletRequest request) throws Exception {
            fileName = new String(fileName.getBytes("iso8859-1"), "UTF-8");
            // 上传的文件都是保存在/WEB-INF/upload目录下的子目录当中
            String fileSaveRootPath = request.getSession().getServletContext().getRealPath("/WEB-INF/upload");
            // 通过文件名找出文件的所在目录
            String path = findFileSavePathByFileName(fileName, fileSaveRootPath);
            // 得到要下载的文件
            File file = new File(path + "\" + fileName);
            // 如果文件不存在
            ResultModel rm = new ResultModel();
            if (!file.exists()) {
                rm.setMessage("您要下载的资源不存在!!");
                rm.setSuccess(false);
            }
            // 处理文件名
            String realname = fileName.substring(fileName.indexOf("_") + 1);
            // 设置响应头,控制浏览器下载该文件
            response.setHeader("content-disposition", "attachment;filename=" + URLEncoder.encode(realname, "UTF-8"));
            // 读取要下载的文件,保存到文件输入流
            FileInputStream in = new FileInputStream(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; // upload23
                                                                    // upload35
            File file = new File(dir);
            if (!file.exists()) {
                // 创建目录
                file.mkdirs();
            }
            return dir;
        }
    
    }

    FileService:

    package com.activiti.service;
    
    import java.util.List;
    
    import javax.servlet.http.HttpServletRequest;
    import javax.servlet.http.HttpServletResponse;
    
    import org.springframework.web.multipart.MultipartFile;
    
    import com.cinms.common.ResultModel;
    
    /**
    * @author Jump
    * @version 创建时间:2018年6月20日 上午10:26:53
    * 类说明
    */
    public interface FileService {
    
        ResultModel upload(List<MultipartFile> files, HttpServletRequest request);
        
        void download(String fileName, HttpServletResponse response, HttpServletRequest request) throws Exception;
    }

     前端:

  • 相关阅读:
    let 和 const 命令
    python连接oracle
    Python中小整数对象池和大整数对象池
    前端内容流程导图
    bootstrap插件的一些常用属性介绍
    bootstrap的引入和使用
    Linux 重定向
    Mongodb 备份 数据导出导入
    Mongodb 副本集
    Redis 模糊查询删除操作
  • 原文地址:https://www.cnblogs.com/XJJD/p/9335031.html
Copyright © 2011-2022 走看看