SpringMVC文件上傳及查看的示例代碼
寫(xiě)在前面
談到文件上傳,首先要說(shuō)業(yè)務(wù)邏輯,如果上傳的文件大家都可以看(比如廣告或者首頁(yè)的banner)等,那么我們就把圖片放在靜態(tài)資源區(qū)(與css,js一樣的位置)中,如果文件是受保護(hù)的(像用戶只能查看自己上傳的照片),那么我們就把它存放在服務(wù)器中的某個(gè)專門(mén)存放圖片的位置。
本例分別展示了存放在兩個(gè)位置的上傳文件的方法,上傳之后,作為延伸,還添加了查看上傳的文件以及下載已經(jīng)上傳的文件的功能。
準(zhǔn)備工作
配置SpringMVC,導(dǎo)入commons包
在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、存放位置:
存放在項(xiàng)目中,所以路徑為相對(duì)項(xiàng)目的路徑。
/{yourproject}/webapp/static/img
2、配置響應(yīng)的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()) {
//獲取目標(biāo)文件夾
String path = request.getServletContext().getRealPath("/") + "static/img/";
//獲取用戶上傳的源文件名
String fileName = file.getOriginalFileName();
//新建文件
File file1 = new File(path, fileName);
//將文件寫(xiě)入
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";
}
}
}
存放在服務(wù)器
1、本例存放位置:
存放在服務(wù)器某個(gè)位置,與項(xiàng)目無(wú)關(guān),所以地址為絕對(duì)路徑。
/Users/mac/Desktop/imgtemp/, 為目錄的絕對(duì)路徑。
2、配置響應(yīng)的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);
//寫(xiě)入文件
file.transferTo(file1);
}
}
...
延伸部分(文件的查看及下載)
由于響應(yīng)是要以流的形式傳遞文件,我們需要正確的設(shè)置響應(yīng)的MIMIE類型才能被瀏覽器正確的解析,應(yīng)用程序文件的默認(rèn)MIMIE類型為 application/octet-stream,MIME設(shè)置為該值后,瀏覽器不會(huì)自動(dòng)執(zhí)行或詢問(wèn)執(zhí)行這類文件,會(huì)以對(duì)待附件的形式直接將文件下載至本地。
更多關(guān)于MIMIE的解讀請(qǐng)查看這篇文章
如果我們?nèi)绻胱远x下載文件的名字,那么就需要設(shè)置Content-Disposition消息。
Content-Disposition 消息頭指示回復(fù)的內(nèi)容該以何種形式展示,是以內(nèi)聯(lián)的形式(即網(wǎng)頁(yè)或者頁(yè)面的一部分),還是以附件的形式下載并保存到本地。
更過(guò)關(guān)于Content-Disposition的解讀請(qǐng)查看這篇文章
...
@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;
}
//如果請(qǐng)求參數(shù)saveName不為空,進(jìn)行文件的下載
if(!StringUtils.isEmpty(saveName)) {
//設(shè)置響應(yīng)長(zhǎng)度
response.setContentLength((int)file.length());
//設(shè)置響應(yīng)的MIME類型為application/octet-stream
response.setContentType(MediaType.APPLICATION_OCTET_STREAM_VALUE);
saveName = new String(saveName.getBytes("UTF-8"),"ISO8859-1");
//設(shè)置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)化器來(lái)將文件輸出,該轉(zhuǎn)換器實(shí)現(xiàn) HttpMessageConverter 接口??勺x取所有MIME的請(qǐng)求信息,響應(yīng)信息的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" rel="external nofollow" >
</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" rel="external nofollow" target="_blank">使用默認(rèn)方式查看上傳至Disk的dubbo圖片</a>
</button>
<button class="btn btn-default">
<a href="/download/byDefault?fileName=dubbo.png&saveName=dubb.png" rel="external nofollow" >使用默認(rèn)方式下載dubbo圖片</a>
</button>
</div>
<div class="container">
<button class="btn btn-default">
<a href="/download/byConvert?fileName=dubbo.png" rel="external nofollow" target="_blank">使用MVC轉(zhuǎn)化器查看上傳至Disk的dubbo圖片</a>
</button>
<button class="btn btn-default">
<a href="/download/byConvert?fileName=dubbo.png&saveName=dub.png" rel="external nofollow" >使用MVC轉(zhuǎn)化器下載上傳至Disk的dubbo圖片</a>
</button>
</div>
</div>
</body>
</html>
以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
java 使用線程做的一個(gè)簡(jiǎn)單的ATM存取款實(shí)例代碼
線程 Thread 類,和 Runable 接口 比較兩者的特點(diǎn)和應(yīng)用領(lǐng)域.可以,直接繼承線程Thread類。該方法編寫(xiě)簡(jiǎn)單,可以直接操作線程,適用于單重繼承情況,因而不能在繼承其他類,下面我們來(lái)看一個(gè)實(shí)例2013-08-08
Guava自動(dòng)加載緩存LoadingCache使用實(shí)戰(zhàn)詳解
這篇文章主要為大家介紹了Guava自動(dòng)加載緩存LoadingCache使用實(shí)戰(zhàn)詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-12-12
springboot+vue項(xiàng)目從第一行代碼到上線部署全流程
本文詳細(xì)介紹了如何從零開(kāi)始搭建一個(gè)基于Spring Boot和Vue.js的前后端分離項(xiàng)目,并涵蓋項(xiàng)目需求分析、技術(shù)選型、項(xiàng)目結(jié)構(gòu)設(shè)計(jì)、前后端交互、部署上線等全過(guò)程,感興趣的朋友跟隨小編一起看看吧2024-11-11
Java ==,equals()與hashcode()的使用
本文主要介紹了Java ==,equals()與hashcode()的使用,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2023-05-05
IDEA 如何控制編輯左側(cè)的功能圖標(biāo)ICON(操作步驟)
很多朋友被idea左側(cè)的圖標(biāo)不見(jiàn)了這一問(wèn)題搞的焦頭爛額,不知道該怎么操作,今天小編就交大家如何控制編輯左側(cè)的功能圖標(biāo) ICON,文字內(nèi)容不多,主要通過(guò)兩張截圖給大家說(shuō)明,感興趣的朋友一起看看吧2021-05-05
SpringBoot 鉤子接口的實(shí)現(xiàn)代碼
本文主要介紹了SpringBoot 鉤子接口,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2021-08-08
Java中注解@Async實(shí)現(xiàn)異步及導(dǎo)致失效原因分析
Async注解用于聲明一個(gè)方法是異步的,當(dāng)在方法上加上這個(gè)注解時(shí)將會(huì)在一個(gè)新的線程中執(zhí)行該方法,而不會(huì)阻塞原始線程,這篇文章主要給大家介紹了關(guān)于Java中注解@Async實(shí)現(xiàn)異步及導(dǎo)致失效原因分析的相關(guān)資料,需要的朋友可以參考下2024-07-07
利用Jackson實(shí)現(xiàn)數(shù)據(jù)脫敏的示例詳解
在我們的企業(yè)項(xiàng)目中,為了保護(hù)用戶隱私,數(shù)據(jù)脫敏成了必不可少的操作,那么我們?cè)趺磧?yōu)雅的利用Jackson實(shí)現(xiàn)數(shù)據(jù)脫敏呢,本文就來(lái)和大家詳細(xì)聊聊,希望對(duì)大家有所幫助2023-05-05
SpringBoot使用JavaMailSender實(shí)現(xiàn)發(fā)送郵件
JavaMailSender是Spring Framework中的一個(gè)接口,用于發(fā)送電子郵件,本文主要為大家詳細(xì)介紹了SpringBoot如何使用JavaMailSender實(shí)現(xiàn)發(fā)送郵件,需要的可以參考下2023-12-12
Java使用Condition控制線程通信的方法實(shí)例詳解
這篇文章主要介紹了Java使用Condition控制線程通信的方法,結(jié)合實(shí)例形式分析了使用Condition類同步檢測(cè)控制線程通信的相關(guān)操作技巧,需要的朋友可以參考下2019-09-09

