https://blog.csdn.net/stubbornness1219/article/details/72356632
Springboot對資源的描述提供了相應的接口,其主要實現類有ClassPathResource、FileSystemResource、UrlResource、ByteArrayResource、
ServletContextResource和InputStreamResource。
- ClassPathResource可用來獲取類路徑下的資源文件。假設我們有一個資源文件test.txt在類路徑下,我們就可以通過給定對應資源文件在類路徑下的路徑path來獲取它,new ClassPathResource(“test.txt”)。
- FileSystemResource可用來獲取文件系統里面的資源。我們可以通過對應資源文件的文件路徑來構建一個FileSystemResource。FileSystemResource還可以往對應的資源文件里面寫內容,當然前提是當前資源文件是可寫的,這可以通過其isWritable()方法來判斷。FileSystemResource對外開放了對應資源文件的輸出流,可以通過getOutputStream()方法獲取到。
- UrlResource可用來代表URL對應的資源,它對URL做了一個簡單的封裝。通過給定一個URL地址,我們就能構建一個UrlResource。
- ByteArrayResource是針對於字節數組封裝的資源,它的構建需要一個字節數組。
- ServletContextResource是針對於ServletContext封裝的資源,用於訪問ServletContext環境下的資源。ServletContextResource持有一個ServletContext的引用,其底層是通過ServletContext的getResource()方法和getResourceAsStream()方法來獲取資源的。
- InputStreamResource是針對於輸入流封裝的資源,它的構建需要一個輸入流。
Resource接口中主要定義有以下方法:
- exists():用於判斷對應的資源是否真的存在。
- isReadable():用於判斷對應資源的內容是否可讀。需要注意的是當其結果為true的時候,其內容未必真的可讀,但如果返回false,則其內容必定不可讀。
- isOpen():用於判斷當前資源是否代表一個已打開的輸入流,如果結果為true,則表示當前資源的輸入流不可多次讀取,而且在讀取以后需要對它進行關閉,以防止內存泄露。該方法主要針對於InputStreamResource,實現類中只有它的返回結果為true,其他都為false。
- getURL():返回當前資源對應的URL。如果當前資源不能解析為一個URL則會拋出異常。如ByteArrayResource就不能解析為一個URL。
- getFile():返回當前資源對應的File。如果當前資源不能以絕對路徑解析為一個File則會拋出異常。如ByteArrayResource就不能解析為一個File。
- getInputStream():獲取當前資源代表的輸入流。除了InputStreamResource以外,其它Resource實現類每次調用getInputStream()方法都將返回一個全新的InputStream。
- 以及一些類似於Java中的File的接口,比如getName,getContenLength等等。
如果需要獲取本地文件系統中的指定路徑下的文件,有一下幾種方式
- 通過ResponseEntity<InputStreamResource>實現
- 通過寫HttpServletResponse的OutputStream實現
第一種方式通過封裝ResponseEntity,將文件流寫入body中。這里注意一點,就是文件的格式需要根據具體文件的類型來設置,一般默認為application/octet-stream。文件頭中設置緩存,以及文件的名字。文件的名字寫入了,都可以避免出現文件隨機產生名字,而不能識別的問題。
- @RequestMapping(value = "/media", method = RequestMethod.GET)
- public ResponseEntity<InputStreamResource> downloadFile( Long id)
- throws IOException {
- String filePath = "E:/" + id + ".rmvb";
- FileSystemResource file = new FileSystemResource(filePath);
- HttpHeaders headers = new HttpHeaders();
- headers.add("Cache-Control", "no-cache, no-store, must-revalidate");
- headers.add("Content-Disposition", String.format("attachment; filename=\"%s\"", file.getFilename()));
- headers.add("Pragma", "no-cache");
- headers.add("Expires", "0");
- return ResponseEntity
- .ok()
- .headers(headers)
- .contentLength(file.contentLength())
- .contentType(MediaType.parseMediaType("application/octet-stream"))
- .body(new InputStreamResource(file.getInputStream()));
- }
第二種方式采用了Java中的File文件資源,然后通過寫response的輸出流,放回文件。
- @RequestMapping(value="/media/", method=RequestMethod.GET)
- public void getDownload(Long id, HttpServletRequest request, HttpServletResponse response) {
- // Get your file stream from wherever.
- String fullPath = "E:/" + id +".rmvb";
- File downloadFile = new File(fullPath);
- ServletContext context = request.getServletContext();
- // get MIME type of the file
- String mimeType = context.getMimeType(fullPath);
- if (mimeType == null) {
- // set to binary type if MIME mapping not found
- mimeType = "application/octet-stream";
- System.out.println("context getMimeType is null");
- }
- System.out.println("MIME type: " + mimeType);
- // set content attributes for the response
- response.setContentType(mimeType);
- response.setContentLength((int) downloadFile.length());
- // set headers for the response
- String headerKey = "Content-Disposition";
- String headerValue = String.format("attachment; filename=\"%s\"",
- downloadFile.getName());
- response.setHeader(headerKey, headerValue);
- // Copy the stream to the response's output stream.
- try {
- InputStream myStream = new FileInputStream(fullPath);
- IOUtils.copy(myStream, response.getOutputStream());
- response.flushBuffer();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
//文件下載相關代碼 @RequestMapping("/download") public String downloadFile(HttpServletRequest request, HttpServletResponse response) { String fileName = "b60bcf72-219d-4e92-88de-ed6b0ad9b0e7-2018-04-23-14-09-14.xls";// 設置文件名,根據業務需要替換成要下載的文件名 if (fileName != null) { //設置文件路徑 String realPath = "D:\\eclipsworksapce1\\upgrade\\src\\main\\webapp\\upload\\tbox\\456789\\"; File file = new File(realPath , fileName); if (file.exists()) { response.setContentType("application/octet-stream");// response.setHeader("content-type", "application/octet-stream"); response.setHeader("Content-Disposition", "attachment;fileName=" + fileName);// 設置文件名 byte[] buffer = new byte[1024]; FileInputStream fis = null; BufferedInputStream bis = null; try { fis = new FileInputStream(file); bis = new BufferedInputStream(fis); OutputStream os = response.getOutputStream(); int i = bis.read(buffer); while (i != -1) { os.write(buffer, 0, i); i = bis.read(buffer); } System.out.println("success"); } catch (Exception e) { e.printStackTrace(); } finally { if (bis != null) { try { bis.close(); } catch (IOException e) { e.printStackTrace(); } } if (fis != null) { try { fis.close(); } catch (IOException e) { e.printStackTrace(); } } } } } return null; }