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

    文件上传下载

    使用spring-mvc,完成文件上传与下载功能

    jar包依赖

    <!--文件上传-->
    <dependency>    
        <groupId>commons-io</groupId>   
        <artifactId>commons-io</artifactId>    
        <version>2.6</version>
    </dependency>
    <dependency>  
        <groupId>commons-fileupload</groupId>  
        <artifactId>commons-fileupload</artifactId>   
        <version>1.3.2</version>
    </dependency>
    

    spring-mvc.xml文件配置

    <!--文件上传-->
    <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">    
        <property name="defaultEncoding" value="UTF-8"/>    
        <property name="maxUploadSize" value="#{10*1024*1024}"/>
    </bean>
    

    上传

    文件上传分为三种:单文件上传、多文件上传、异步上传

    单文件上传

    HTML代码

    <form method="post" action="../testUpload" enctype="multipart/form-data">    
        <input type="file" name="file"/>   
        <input type="submit" value="submit"/>
    </form>
    

    注意:

    1. form表单中要设置enctype属性为multipart/form-data,使用二进制流的形式发送数据
    2. 用于上传文件的input要设置type为file

    后台中使用MultipartFile参数即可接收传递过来的二进制文件数据
    Java代码

    @RequestMapping("/upload")
    public String upload(@RequestParam("file") MultipartFile file, Model model, HttpServletRequest request) throws IOException {    
        if (!file.isEmpty()) {       
            // 获取文件路径
            String path = request.getSession().getServletContext().getRealPath("/static/upload");  
            // 获取原始文件名
            String filename = file.getOriginalFilename();        
            // 使用时间戳重新命名文件,避免文件重名
            SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");        
            String prefix = simpleDateFormat.format(new Date());        
            String suffix = filename.substring(filename.lastIndexOf("."));        
            String newFileName = prefix + suffix;   
            // 创建目标文件对象
            File descFile = new File(path + "/" + newFileName);        
            // 如果目标路径不存在
            if (!descFile.getParentFile().exists()) {            
                descFile.mkdirs();        
            }        
            // 如果目标文件不存在
            if (!descFile.exists()) {            
                file.transferTo(descFile);            
                model.addAttribute("file", newFileName);        
            }    
        }    
        return "front/ok";
    }
    

    多文件上传

    多文件上传的思路就是将多个文件分开,对每个文件使用单文件上传的方法即可。但是这其中又分为两种情况:一为在同一个文件框中一次选择多个文件上传,二为在多个文件框中同时选择文件上传

    情况一 单个文件框内选择多个文件

    此情况与单文件上传相比需要在input中添加multiple属性,它可以使我们在这个input框中同时选择多个文件上传
    HTML代码

    <form method="post" action="../testUpload2" enctype="multipart/form-data">    
        <input type="file" name="file" multiple="multiple"/>    
        <input type="submit" value="submit"/>
    </form>
    

    与单文件上传相比,后台中我们只需要将MultipartFile参数改为数组形式即可接收传递来的一组二进制文件数据,之后对这个数组进行遍历使用单文件上传的方法即可。
    Java代码

    @RequestMapping("/testUpload2")
    public String upload2(HttpSession session, @RequestParam("file") MultipartFile[] multipartFiles) throws IOException {    
        int i = 1;    
        if (multipartFiles != null && multipartFiles.length > 0) {        
            String path = session.getServletContext().getRealPath("/static/upload");        
            for (MultipartFile file : multipartFiles) {            
                String filename = file.getOriginalFilename();            
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");            
                String prefix = simpleDateFormat.format(new Date());            
                String suffix = filename.substring(filename.lastIndexOf("."));            
                String newFileName = prefix + i + suffix;            
                File descFile = new File(path + "/" + newFileName);            
                if (!descFile.getParentFile().exists()) {                
                    descFile.mkdirs();            
                }           
                if (!descFile.exists()) {                
                    file.transferTo(descFile);            
                }           
                i++;       
                }  
            }  
        return "front/ok";
    }
    

    情况二 多个文件框同时上传文件

    form表单中同时存在多个有相同name值的file类型input
    HTML代码

    <form method="post" action="../testUpload" enctype="multipart/form-data">    
        <input type="file" name="file"/>    
        <input type="file" name="file"/>    
        <input type="submit" value="submit"/>
    </form>
    

    此种情况下我们在后台不能再使用MultipartFile来接受文件,而要使用MultipartRequest参数来进行文件获取。
    Java代码

    @RequestMapping("/testUpload")
    public String upload(HttpSession session, MultipartRequest multipartRequest) throws IOException {    
        // 使用MultipartRequest.getFiles()方法获取所有同名文件框中的文件
        List<MultipartFile> files = multipartRequest.getFiles("file");    
        int i = 1;   
        if ( files.size() > 0 ) {       
            String path = session.getServletContext().getRealPath("/static/upload");      
            for (MultipartFile file : files) {         
                String filename = file.getOriginalFilename();         
                SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyyMMddHHmmss");           
                String prefix = simpleDateFormat.format( new Date() );          
                String suffix = filename.substring(filename.lastIndexOf("."));          
                String newFileName = prefix + i + suffix;          
                File descFile = new File( path + "/" + newFileName );         
                if ( !descFile.getParentFile().exists() ) {             
                    descFile.mkdirs();         
                }        
                if ( !descFile.exists() ) {      
                    file.transferTo(descFile);         
                }         
                i++;  
            }  
        }   
        return "front/ok";
    }
    

    异步上传

    异步上传与前两种方式相比,区别在于使用ajax技术向后台发送文件

    JavaScript代码

    function uploadData(){
        var fdata = new FormData(mygoodsform);//提取表单数据
        //通过 ajax将数据发送到 后台
        $.ajax({
            url:"/EasyUIDemo/emp/uploadData.do",
            type:"post",
            data:fdata,
            processData:false,
            contentType:false,
            success:function(resp){
                // do something
            }
        });
    }
    

    提取表单数据的两种方式:

    1. js方式 new FormData(表单id)
    2. jQuery方式 new FormData($("#表单id")[0])

    两个关键属性:
    processData
    要求为Boolean类型的参数,默认为true。默认情况下,发送的数据将被转换为对象(从技术角度来讲并非字符串)以配合默认内容类 型"application/x-www-form-urlencoded"。如果要发送DOM树信息或者其他不希望转换的信息,请设置为false。
    contentType
    要求为String类型的参数,当发送信息至服务器时,内容编码类型默认为"application/x-www-form-urlencoded"。该默认值适合大多数应用场合。

    下载

    下载有两种方式:其一为通过a标签指向文件路径进行下载,其二为通过后台代码控制浏览器进行下载。

    方式一 a标签

    HTML代码

    <a href="../static/upload/111.sql">下载</a>
    

    此种方式有诸多缺点:

    1. 如果目标文件是图片类型,则会直接打开图片,需要右击超链接点击另存为进行下载
    2. 容易出现中文乱码问题
    3. 不能进行多文件下载

    方式二 后台代码控制浏览器下载(多文件下载)

    单文件下载
    Java代码

    @RequestMapping("/down")
    public ResponseEntity<byte[]> download(@RequestParam("filename") String filename, HttpServletRequest request) throws IOException {    
        String path = request.getSession().getServletContext().getRealPath("/static/upload");    
        File file = new File(path + "/" + filename);    
        //文件名(中文)转码    
        String encodedFileName = null;  
        String userAgentString = request.getHeader("User-Agent");   
        if (userAgentString.indexOf("Chrome") > 0 || userAgentString.indexOf("FireFox") > 0) {       
            encodedFileName = URLEncoder.encode(filename, "UTF-8").replaceAll("\+","%20");  
        } else {        
            encodedFileName = MimeUtility.encodeWord(filename);   
        }    
        //数据,将要下载的文件对象转换成字节数组   
        byte[] data = FileUtils.readFileToByteArray(file);   
        HttpHeaders headers = new HttpHeaders();   
        //设置响应文档类型,二进制形式    
        headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);   
        //弹出下载窗口,并指定文件名    
        headers.setContentDispositionFormData("attachment", encodedFileName);   
        //状态码   
        HttpStatus status = HttpStatus.CREATED;    
        ResponseEntity<byte[]> responseEntity = new ResponseEntity<byte[]>(data, headers, status);   
        return responseEntity;
    }
    

    多文件下载:将多个文件先打包成zip文件,再使用单文件下载的方法下载这个zip即可
    Java代码

    @RequestMapping("downloadHomeworks.do")
    public void downloadHomewords(String paths, HttpServletRequest request, HttpServletResponse response) {
        String tmpFileName = "homeworks.zip";
        byte[] buffer = new byte[1024];
        String strZipPath = "D:/hw/" + UUID.randomUUID() + tmpFileName;
        try {
            ZipOutputStream out = new ZipOutputStream(new FileOutputStream(strZipPath));
            String replace = paths.replace(',', ' ');
            String[] files = replace.split(" ");
            // 下载的文件集合
            for (int i = 0; i < files.length; i++) {
                FileInputStream fis = new FileInputStream(files[i]);
                out.putNextEntry(new ZipEntry(files[i].substring(6)));
                // 设置压缩文件内的字符编码,不然会变成乱码
                // out.setEncoding("GBK");
                int len;
                // 读入需要下载的文件的内容,打包到zip文件
                while ((len = fis.read(buffer)) > 0) {
                    out.write(buffer, 0, len);
                }
                out.closeEntry();
                fis.close();
            }
        out.flush();
        out.close();
        // 调用单文件下载的方法下载打包好的压缩文件
        downloadHomeword(strZipPath, request, response);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
  • 相关阅读:
    解决GitHub下载速度太慢的问题
    java监测硬盘空间大小
    @SuppressWarnings注解用法详解
    No goals have been specified for this build.
    java新建excel文件导出(HSSFWorkbook)
    mysql日志文件路径
    获取select框下option所有值
    jquery获取select选中的值
    mysql查看查询缓存是否启用
    Kafka消息重新发送
  • 原文地址:https://www.cnblogs.com/voidchar/p/11361897.html
Copyright © 2011-2022 走看看