SpringMVC文件上傳及查看

寫在前面

談到文件上傳,首先要說業(yè)務邏輯,如果上傳的文件大家都可以看(比如廣告或者首頁的banner)等,那么我們就把圖片放在靜態(tài)資源區(qū)(與css,js一樣的位置)中如果文件是受保護的(像用戶只能查看自己上傳的照片),那么我們就把它存放在服務器中的某個專門存放圖片的位置。
本例分別展示了存放在兩個位置的上傳文件的方法,上傳之后,作為延伸,還添加了查看上傳的文件以及下載已經(jīng)上傳的文件的功能。

準備工作

  1. 配置SpringMVC,導入commons包
  2. 在mvc-servlet.xml中配置文件上傳解析器
<!--文件上傳解析器-->
  <bean id="multipartResolver"
        class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
      <property name="maxUploadSize" value="1000000"/>
      <property name="defaultEncoding" value="UTF-8" />
  </bean>

存放在靜態(tài)資源區(qū)

  1. 存放位置:
    存放在項目中,所以路徑為相對項目的路徑。
    /{yourproject}/webapp/static/img

  2. 配置響應的handler

@Controller
public class UploadController {
  @GetMapping("/upload")
  public String UploadHandler() {
    return "upload";
  }

  @PostMapping("/upload/static")
  public void wriToStatic(HttpServletRequest request,
                          RedirectAttributes redirectAttributes,
                          @RequestParam("fileName") MultipartFile file) {
    if(!file.isEmpty()) {
      //獲取目標文件夾
      String path = request.getServletContext().getRealPath("/") + "static/img/";
      //獲取用戶上傳的源文件名
      String fileName = file.getOriginalFileName();
      //新建文件
      File file1 = new File(path, fileName);
      //將文件寫入
      file.transferTo(file1);

      redirectAttributes.addFlashAttribute("message","upload to static success");
      return "redirect:/upload";
    } else {
      redirectAttributes.addFlashAttribute("message","upload file can not be empty");
      return "redirect:/upload";
    }

  }
}

存放在服務器

  1. 本例存放位置:
    存放在服務器某個位置,與項目無關,所以地址為絕對路徑。
    /Users/mac/Desktop/imgtemp/, 為目錄的絕對路徑。

  2. 配置響應的handler

...
@PostMapping("/upload/disk")
public String writeToDisk(HttpServletRequest request,
                          @RequestParam("fileName") MultipartFile file,
                          RedirectAttributes redirectAttributes) {
  if(!file.isEmpty()) {
    //獲取源文件名
    String fileName = file.getOriginalFileName();
    //獲取保存文件文件夾路徑
    String path = "/Users/mac/Desktop/imgtemp/";
    //新建文件
    File file1 = new File(path,fileName);
    //寫入文件
    file.transferTo(file1);
  }

}
...

延伸部分(文件的查看及下載)

由于響應是要以流的形式傳遞文件,我們需要正確的設置響應的MIMIE類型才能被瀏覽器正確的解析,應用程序文件的默認MIMIE類型為 application/octet-stream,MIME設置為該值后,瀏覽器不會自動執(zhí)行或詢問執(zhí)行這類文件,會以對待附件的形式直接將文件下載至本地。

更多關于MIMIE的解讀請查看這篇文章

如果我們?nèi)绻胱远x下載文件的名字,那么就需要設置Content-Disposition消息。
Content-Disposition 消息頭指示回復的內(nèi)容該以何種形式展示,是以內(nèi)聯(lián)的形式(即網(wǎng)頁或者頁面的一部分),還是以附件的形式下載并保存到本地。

更過關于Content-Disposition的解讀請查看這篇文章

...
@GetMapping("/download/byDefault")
public void getImgByDefault(@RequestParam String fileName,
                            @RequestParam(required=false,defaultValue="") String saveName),
                            HttpServletResponse response {
    if(StringUtils.isEmpty(fileName)) {
      response.sendError(404);
      return;
    }
    //文件存放的路徑
    String path = "/Users/mac/Desktop/imgtemp/";
    //新建文件
    File file = new File(path,fileName);

    if(!file.exists()) {
      response.sendError(404);
      return;
    }
    //如果請求參數(shù)saveName不為空,進行文件的下載
    if(!StringUtils.isEmpty(saveName)) {
      //設置響應長度
      response.setContentLength((int)file.length());
      //設置響應的MIME類型為application/octet-stream
      response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);

      saveName = new String(saveName.getBytes("UTF-8"),"ISO8859-1");
      //設置content-disposition為attachment;fileName=saveName
      response.setHeader(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\""+saveName+"\"");
    }
    //讀取文件
    InputStream is = new FileInputStream(file);
    OutputStream os = response.getOutputStream();
    //將文件以流的形式輸出
    IOUtils.copy(is,os);
    os.flush();
    os.close();
    is.close();

}

我們還可以使用SpringMVC自帶的 ByteArrayHttpMessageConverter 轉(zhuǎn)化器來將文件輸出,該轉(zhuǎn)換器實現(xiàn) HttpMessageConverter 接口??勺x取所有MIME的請求信息,響應信息的MIME為 application/octet-stream

...
@GetMapping("/download/byConvert")
public HttpEntity<byte[]> getImgByConvert(@RequestParam String fileName,
                                          @RequestParam(required=false,defaultValue="") String saveName) {
    if(StringUtils.isEmpty(fileName)) {
      return new ResponseEntity<>(HttpStatus.NOT_FOUND);
    }

    String path = "/Users/mac/Desktop/imgtemp/";
    File file = new File(path,fileName);

    if(!file.exists()) {
      return new ResponseEntity<>(HttpStatus.NOT_FOUND);
    }

    HttpHeaders headers = new HttpHeaders();
    if(!StringUtils.isEmpty(saveName)) {
      headers.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
      headers.setContentLength(file.length());

      saveName = new Sting(saveName.getBytes("UTF-8"),"ISO8859-1");
      headers.add(HttpHeaders.CONTENT_DISPOSITION,"attachment;fileName=\"" + saveName + "\"");
    } else {
      headers.setContentType(MediaType.IMAGE_PNG);
    }

    return new HttpEntity<>(FileCopyUtils.copyToByteArray(file),headers);

}

upload.jsp

<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!doctype html>
<html>
<head>
    <meta charset="UTF-8">
    <meta name="viewport"
          content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
    <meta http-equiv="X-UA-Compatible" content="ie=edge">
    <title>Document</title>
    <link rel="stylesheet" href="/static/bootstrap-3.3.5-dist/css/bootstrap.css">
</head>
<body>
<div class="container">
    <h1 class="text-center">上傳文件撒</h1>
    <c:if test="${not empty message}">
        <h2>${message}</h2>
    </c:if>


    <form:form enctype="multipart/form-data" action="/upload/static">
        <p class="text-info">上傳至/web/static</p>
        <label for="">上傳文件:</label>
        <input type="file" name="uploadFile">

        <button class="btn btn-default">提交</button>
    </form:form>



    <form:form enctype="multipart/form-data" action="/upload/disk">
        <p class="text-info">上傳至Disk</p>
        <label for="">上傳文件</label>
        <input type="file" name="uploadFile">

        <button class="btn btn-default">提交</button>
    </form:form>

    <div class="container">
        <button class="btn btn-default">
            <a href="/download/byDefault?fileName=dubbo.png" target="_blank">使用默認方式查看上傳至Disk的dubbo圖片</a>
        </button>
        <button class="btn btn-default">
            <a href="/download/byDefault?fileName=dubbo.png&saveName=dubb.png">使用默認方式下載dubbo圖片</a>
        </button>
    </div>

    <div class="container">
        <button class="btn btn-default">
            <a href="/download/byConvert?fileName=dubbo.png" target="_blank">使用MVC轉(zhuǎn)化器查看上傳至Disk的dubbo圖片</a>
        </button>
        <button class="btn btn-default">
            <a href="/download/byConvert?fileName=dubbo.png&saveName=dub.png">使用MVC轉(zhuǎn)化器下載上傳至Disk的dubbo圖片</a>
        </button>

    </div>
</div>
</body>
</html>
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內(nèi)容

  • Spring Cloud為開發(fā)人員提供了快速構建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,545評論 19 139
  • 本文包括:1、文件上傳概述2、利用 Commons-fileupload 組件實現(xiàn)文件上傳3、核心API——Dis...
    廖少少閱讀 12,743評論 5 91
  • iOS開發(fā)系列--網(wǎng)絡開發(fā) 概覽 大部分應用程序都或多或少會牽扯到網(wǎng)絡開發(fā),例如說新浪微博、微信等,這些應用本身可...
    lichengjin閱讀 4,034評論 2 7
  • Spring Boot 參考指南 介紹 轉(zhuǎn)載自:https://www.gitbook.com/book/qbgb...
    毛宇鵬閱讀 47,268評論 6 342
  • 43期溫州親子班 【30天月度檢視】姓名吳小軍 #基本情況#(寫孩子的) 姓名:柯夕樹 年齡:8歲 小組:第1組 ...
    吳小軍Wuxiaojun閱讀 352評論 0 0

友情鏈接更多精彩內(nèi)容