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

    文件上传

    (1)下载添加2个jar包

    • commons-fileupload.jar
    • commons-io.jar

    SpringMVC的文件上传依赖于Apache的FileUpload组件,需要下载添加2个jar包,下载地址:

    http://commons.apache.org/proper/commons-fileupload/

    http://commons.apache.org/proper/commons-io/

    (2)表单

      <form action="${pageContext.request.contextPath}/fileUpload" method="post" enctype="multipart/form-data">
        选择文件:<input name="uploadFile" type="file" multiple /><br />
        <button type="submit">上传</button>
      </form>

    multiple用于文件多选,不使用multiple则只能选择一个文件。

    (3)controller

    @org.springframework.stereotype.Controller
    public class FileUploadController{
    
        @RequestMapping("/fileUpload")
        public String fileUpload(@RequestParam("uploadFile") List<MultipartFile> fileList, HttpServletRequest request) {
            //如果用户上传了文件
            if (!fileList.isEmpty() && fileList.size()>0){
                System.out.println(fileList.isEmpty());
                System.out.println(fileList.size());
                //设置保存路径为项目根目录下的upload文件夹
                String savePath = request.getServletContext().getRealPath("/upload");
                //不存在就新建
                File saveDir = new File(savePath);
                if (!saveDir.exists()){
                    saveDir.mkdirs();
                }
    
                //循环读取上传文件并保存
                for (MultipartFile file:fileList){
                    //原文件名
                    String originalFilename = file.getOriginalFilename();
                    //使用uuid防止文件重名,因为原文件名中包含扩展名,只能放最后面
                    String newFilename= UUID.randomUUID()+"_"+originalFilename;
                    System.out.println(originalFilename);
                    //将临时文件保存至指定目录
                    try {
                        file.transferTo(new File(saveDir+"/"+newFilename));
                    } catch (IOException e) {
                        e.printStackTrace();
                        return "error";
                    }
    
                }
                return "success";
            }
            //如果用户未上传文件,返回error
            return "error";
        }
    
    }

    SpringMVC用MultipartFile来封装上传文件,一个MultipartFile对应一个上传文件。

    (4)SpringMVC的配置文件

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xmlns:context="http://www.springframework.org/schema/context"
           xmlns:mvc="http://www.springframework.org/schema/mvc"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context https://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd">
    
        <!--包扫描-->
        <context:component-scan base-package="com.chy.controller" />
    
        <!--注解驱动,自动注册HandlerMapping、HandlerAdapter-->
        <mvc:annotation-driven />
    
        <!--视图解析器-->
        <bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
            <!--前缀-->
            <property name="prefix" value="/WEB-INF/jsp/" />
            <!--后缀-->
            <property name="suffix" value=".jsp" />
        </bean>
    
        <!-- 配置MultipartResolver,bean的id或name必须为multipartResolver -->
        <bean name="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
            <!-- 上传文件使用的编码字符集-->
            <property name="defaultEncoding" value="utf-8" />
            <!-- 所允许上传文件的最大尺寸,单位字节-->
            <property name="maxUploadSize" value="10485760" />
        </bean>
        
    </beans>

    只需配置MultipartResolver。


    文件下载

    (1)前端传递文件名

    <a href="${pageContext.request.contextPath}/download?filename=1.jpg">下载文件</a>

    (2)controller

    @org.springframework.stereotype.Controller
    public class DownloadController{
    
        @RequestMapping("/download")
        public ResponseEntity<byte[]> fileDownload(HttpServletRequest request,String filename) throws IOException {
            //指定存放文件的路径,此路径是在部署项目下,/表示部署项目的根路径
            String dir=request.getServletContext().getRealPath("/files");
            File file = new File(dir + "/" + filename);
    
            //设置响应头
            HttpHeaders httpHeaders = new HttpHeaders();
            //通知浏览器以下载的方式处理,第二个参数指定文件名
            httpHeaders.setContentDispositionFormData("attachment", filename);
            //以流的形式返回
            httpHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM);
    
            //读取目标文件
            byte[] arr = FileUtils.readFileToByteArray(file);
            //创建ResponseEntity对象并返回。目标文件的byte[]、HttpHeaders、Http状态码
            return new ResponseEntity<>(arr, httpHeaders, HttpStatus.OK);
        }
    
    }

    读取目标文件为byte[ ],使用的FileUtils是commons-io.jar中的类,所以要添加commons-io.jar。

    也可以使用jdk自带的方式读取目标文件为byte[ ]:

        FileInputStream fileInputStream = new FileInputStream(file);
        byte[] arr = fileInputStream.readAllBytes();

    不需要添加额外的jar包。


    解决下载文件,中文文件名乱码的问题

    上面的代码,如果文件名中有中文,文件名会乱码。

    原因在于此句代码中的文件名未指定编码字符集:

     

    httpHeaders.setContentDispositionFormData("attachment", filename);

    浏览器拿到文件名,发现没有指定字符集,就使用浏览器默认的字符集,

    很多浏览器的默认字符集是ISO-8859,不包含中文字符,无法处理文件名里的中文,从而文件名乱码。

    解决方式:

    httpHeaders.setContentDispositionFormData("attachment", URLEncoder.encode(filename,"utf-8"));

    对文件名使用utf-8编码。

    此种方式只对部分浏览器有效。

    不同的浏览器,默认的编码字符集可能不同,解决方式也可能不同,需要根据User-Agent(浏览器内核)来分别处理。

  • 相关阅读:
    Balanced Binary Tree
    Swap Nodes in Pairs
    Reverse Nodes in k-Group
    Reverse Linked List II
    Remove Nth Node From End of List
    Remove Duplicates from Sorted List II
    Remove Duplicates from Sorted List
    Partition List
    Merge Two Sorted Lists
    【Yii2.0】1.2 Apache检查配置文件语法
  • 原文地址:https://www.cnblogs.com/chy18883701161/p/12252978.html
Copyright © 2011-2022 走看看