• 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(浏览器内核)来分别处理。

  • 相关阅读:
    几个可以通过curl查询公网IP的站点
    CentOS安装 netdata 实时监视 Linux 系统性能
    Linux用ifconfig设置IP、掩码、网关
    Linux添加用户(user)到用户组(group)
    使用密码登陆Amazon EC2
    ulimit 命令详解
    linux命令行光标移动技巧
    阿里云epel源
    用scp实现多服务器文件分发
    2019年春季第二周作业
  • 原文地址:https://www.cnblogs.com/chy18883701161/p/12252978.html
Copyright © 2020-2023  润新知