SpringMVC 文件的上傳、下載

 

文件上傳

(1)下載添加2個jar包

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

SpringMVC的文件上傳依賴於Apache的FileUpload組件,須要下載添加2個jar包,下載地址:前端

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

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

 

 

(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則只能選擇一個文件。apache

 

 

(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。spring-mvc

 

 


 

 

文件下載

(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。mvc

 

也能夠使用jdk自帶的方式讀取目標文件爲byte[ ]:app

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

不須要添加額外的jar包。dom

 

 


 

 

解決下載文件,中文文件名亂碼的問題

上面的代碼,若是文件名中有中文,文件名會亂碼。jsp

 

緣由在於此句代碼中的文件名未指定編碼字符集:

 

httpHeaders.setContentDispositionFormData("attachment", filename);

瀏覽器拿到文件名,發現沒有指定字符集,就使用瀏覽器默認的字符集,

不少瀏覽器的默認字符集是ISO-8859,不包含中文字符,沒法處理文件名裏的中文,從而文件名亂碼。

 

 

解決方式:

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

對文件名使用utf-8編碼。

 

此種方式只對部分瀏覽器有效。

不一樣的瀏覽器,默認的編碼字符集可能不一樣,解決方式也可能不一樣,須要根據User-Agent(瀏覽器內核)來分別處理。

相關文章
相關標籤/搜索