仵航說 前后端分離圾浅,文件上傳下載(springBoot+vue+elementUI)仵老大

1.介紹

本文主要是介紹前后端分離的上傳下載,后端使用的是SpringBoot,持久層用的是mybatis-plus,前端用的Vue,UI用的elementUI,測試了一下,文本,圖片,excel,都是可以上傳下載的,前端就是一個頁面,后端就是一個controller頁面,就可以解決,代碼不清晰的話,我把這個前端的vue 跟 后端的controller代碼,以及本篇文章的MD版本放到了這個鏈接里? https://wwa.lanzous.com/b0cqr478f 密碼:19qb

1.1前端樣子


2.前端

2.1先分享一下前端的全部代碼

<template>

<div>

<center>

?

</center>

<divstyle="float: left;margin-left: 100px">

<!-- ? ?? <router-link to="/reportTools/customQuery" style="color: darkblue">-->

<!-- ? ? ?? 上一步-->

<!-- ? ?? </router-link>-->

<el-buttontype="primary"v-on:click="tocustomQuery">上一步</el-button>

</div>

<divstyle="float: right;margin-right: 100px">

<el-buttontype="primary"v-on:click="saveResource">保存</el-button>

</div>

<br>

<h1>基本信息設(shè)置</h1>

<br>

<br>

<center>

<divstyle="margin-right: 170px">

<el-formref="form":model="form"label-width="120px">

<el-form-itemlabel="報表名稱中文:"style="width: 470px;">

<el-inputv-model="form.reportName"></el-input>

</el-form-item>

<el-form-itemlabel="報表名稱英文:"style="width: 470px;">

<el-inputv-model="form.reportEnName"></el-input>

</el-form-item>

<el-form-itemlabel="報表名稱中英文:"style="width: 470px;">

<el-inputv-model="form.reportChEnName"></el-input>

</el-form-item>

<el-form-itemlabel="報表備注:"style="width: 470px;">

<el-inputv-model="form.remarks"></el-input>

</el-form-item>

<el-form-itemlabel="功能編號"style="width: 470px;">

<el-inputv-model="form.code"></el-input>

</el-form-item>

<el-form-itemlabel="編輯模板:"style="width: 570px;">

<el-inputplaceholder="模板地址"style="width: 200px"disabled></el-input>

<el-uploadclass="upload-demo"

:action="uploadUrl"

:before-upload="handleBeforeUpload"

:on-error="handleUploadError"

:before-remove="beforeRemove"

multiple

:limit="5"

:on-exceed="handleExceed"

:file-list="fileList">

<el-buttonsize="small"type="primary">點(diǎn)擊上傳</el-button>

</el-upload>

<ahref="http://localhost:8080/file/download?fileName=test.xls">下載附件</a>

</el-form-item>

<el-form-itemlabel="模板備注:"style="width: 480px;">

模板用于下載蝉绷,打印EXCEL時使用扣孟。其中&#123;&nbsp;{CURRENT_USER&#125;&nbsp;&#125;表示當(dāng)前用戶名勉耀,

&#123;&nbsp;{TITLE&#125;&nbsp;&#125;表示表頭瘫想,&#123;&nbsp;{DATA&#125;&nbsp;&#125;表示數(shù)據(jù)行醋粟,&#123;&nbsp;{FOOTER&#125;&nbsp;&#125;表示頁腳區(qū)域靡菇。

? ?? 導(dǎo)出的內(nèi)容不可改動重归,頁眉頁腳區(qū)域可以自由編輯。

</el-form-item>

<el-form-item>

<el-selectv-model="form.isPublic"style="width: 350px;">

<el-optionlabel="私有查詢"value="2"></el-option>

<el-optionlabel="公共查詢"value="1"></el-option>

</el-select>

</el-form-item>

<el-form-item>

<el-checkboxlabel="是否打印"v-model="form.isPrinting"true-label="1"false-label="2"></el-checkbox>

<el-checkboxlabel="是否導(dǎo)出"v-model="form.isExport"true-label="1"false-label="2"></el-checkbox>

<el-form-itemtype="hidden"style="width: 470px;">

</el-form-item>

</el-form-item>

</el-form>

</div>

</center>

</div>

</template>

?

<script>

importaxiosfrom'axios'

import{uuid}from'vue-uuid';

exportdefault{

data() {

return{

form: {

reportName:'',

reportEnName:'',

reportChEnName:'',

remarks:'',

code:'',

isPublic:'1',

isPrinting:"1",

isExport:"1",

?

datas:[{},{},{},{}],

A0010011:'',

A0010012:'',

A0010013:'',

A0010014:'',

?

?

?

? ?? },

// uuid1:'',

// cusList:{},

uploadUrl:'file/upload',

fileList: [],

?

?

?? }

? },

created() {

?

console.log("上個頁面?zhèn)鱽淼氖?,sessionStorage)

// this.handleUUIDv1()

this.form.code=this.$uuid.v1()

console.log("頁面刷新后新產(chǎn)生的uuid是",this.form.code)

?

? },

watch:{

reportName:function(newVal,oldVal) {//新值和原值

?

console.log("name改變了 a:"+newVal+" ?? b:"+oldVal)

?

?? }

? },

methods: {

//使用uuid

// handleUUIDv1() {

// ? this.uuid1 = this.$uuid.v1()

// },

//點(diǎn)擊多選按鈕true和false變成1或者2

reset(form){

this.$refs['form'].resetFields();

?? },

//獲取上個頁面?zhèn)鱽淼臄?shù)據(jù)

getcustomQuery() {

?

letreportName=this.form.reportName

sessionStorage.setItem("reportName",reportName)

letreportEnName=this.form.reportEnName

sessionStorage.setItem("reportEnName",reportEnName)

letreportChEnName=this.form.reportChEnName

sessionStorage.setItem("reportChEnName",reportChEnName)

letremarks=this.form.remarks

sessionStorage.setItem("remarks",remarks)

letcode=this.form.code

sessionStorage.setItem("code",code)

letisPublic=this.form.isPublic

sessionStorage.setItem("isPublic",isPublic)

letisPrinting=this.form.isPrinting

sessionStorage.setItem("isPrinting",isPrinting)

letisExport=this.form.isExport

sessionStorage.setItem("isExport",isExport)

?

?

?

console.log("上個頁面?zhèn)鱽淼氖?,sessionStorage)

?? },

// this.$router.push('/reportTools/cusMain'),點(diǎn)擊保存發(fā)送鏈接 并跳轉(zhuǎn)

tocustomQuery(){

this.$router.push('/reportTools/customQuery')

?? },

?

saveResource(){

console.log("當(dāng)前頁面表單的數(shù)據(jù)",this.form)

// sessionStorage.setItem("params",JSON.stringify(this.form))

console.log("sessionStorage中的數(shù)據(jù)",sessionStorage)

this.getcustomQuery()

this.$http.post("http://localhost:8080/reporttools/report-show/addReportShow",sessionStorage).then(

resp=>{

console.log(resp)

//this.$router.push('/reportTools/cusMain')

? ?? })

?? },

handleExceed(files,fileList) {

this.$message.warning(`當(dāng)前限制選擇 5 個文件厦凤,本次選擇了 ${files.length}個文件鼻吮,共選擇了 ${files.length+fileList.length}個文件`);

?? },

beforeRemove(file,fileList) {

returnthis.$confirm(`確定移除 ${file.name}?`);

?? },

handleUploadError(error,file) {

console.log("文件上傳出錯:"+error)

?? },

//測試上傳文件(注意web的上下文)

handleBeforeUpload(file){

console.log("開始上傳较鼓,上傳的文件為:"+file)

letformData=newFormData();

formData.append("multipartFiles",file);

axios({

method:'post',

url:'file/upload',

data:formData,

headers: {'Content-Type':'multipart/form-data'}

}).then((res)=>{

console.log("文件上傳返回:"+res)

}).catch(error=>{

console.log("文件上傳異常:"+error)

? ?? })

?? },

? }

}

</script>

?

<stylescoped>

a{

text-decoration:none;

}

</style>

?

2.2分享一下前端template層的代碼

2.2.1上傳下載template全部代碼

<el-uploadclass="upload-demo"

:action="uploadUrl"

:before-upload="handleBeforeUpload"

:on-error="handleUploadError"

:before-remove="beforeRemove"

multiple

:limit="5"

:on-exceed="handleExceed"

:file-list="fileList">

<el-buttonsize="small"type="primary">點(diǎn)擊上傳</el-button>

</el-upload>

<ahref="http://localhost:8080/file/download?fileName=test.xls">下載附件</a>

2.2.2 上傳代碼

<el-uploadclass="upload-demo"

:action="uploadUrl"

:before-upload="handleBeforeUpload"

:on-error="handleUploadError"

:before-remove="beforeRemove"

multiple

:limit="5"

:on-exceed="handleExceed"

:file-list="fileList">

<el-buttonsize="small"type="primary">點(diǎn)擊上傳</el-button>

</el-upload>

2.2.3下載代碼

下載代碼就是一個a標(biāo)簽

<ahref="http://localhost:8080/file/download?fileName=test.xls">下載附件</a>

2.3分享一下前端script代碼

<script>

importaxiosfrom'axios'

import{uuid}from'vue-uuid';

exportdefault{

data() {

return{

form: {

reportName:'',

reportEnName:'',

reportChEnName:'',

remarks:'',

code:'',

isPublic:'1',

isPrinting:"1",

isExport:"1",

?

datas:[{},{},{},{}],

A0010011:'',

A0010012:'',

A0010013:'',

A0010014:'',

?

?

?

? ?? },

// uuid1:'',

// cusList:{},

uploadUrl:'file/upload',

fileList: [],

?

?

?? }

? },

created() {

?

console.log("上個頁面?zhèn)鱽淼氖?,sessionStorage)

// this.handleUUIDv1()

this.form.code=this.$uuid.v1()

console.log("頁面刷新后新產(chǎn)生的uuid是",this.form.code)

?

? },

watch:{

reportName:function(newVal,oldVal) {//新值和原值

?

console.log("name改變了 a:"+newVal+" ?? b:"+oldVal)

?

?? }

? },

methods: {

//使用uuid

// handleUUIDv1() {

// ? this.uuid1 = this.$uuid.v1()

// },

//點(diǎn)擊多選按鈕true和false變成1或者2

reset(form){

this.$refs['form'].resetFields();

?? },

//獲取上個頁面?zhèn)鱽淼臄?shù)據(jù)

getcustomQuery() {

?

letreportName=this.form.reportName

sessionStorage.setItem("reportName",reportName)

letreportEnName=this.form.reportEnName

sessionStorage.setItem("reportEnName",reportEnName)

letreportChEnName=this.form.reportChEnName

sessionStorage.setItem("reportChEnName",reportChEnName)

letremarks=this.form.remarks

sessionStorage.setItem("remarks",remarks)

letcode=this.form.code

sessionStorage.setItem("code",code)

letisPublic=this.form.isPublic

sessionStorage.setItem("isPublic",isPublic)

letisPrinting=this.form.isPrinting

sessionStorage.setItem("isPrinting",isPrinting)

letisExport=this.form.isExport

sessionStorage.setItem("isExport",isExport)

?

?

?

?

?

?

console.log("上個頁面?zhèn)鱽淼氖?,sessionStorage)

?? },

// this.$router.push('/reportTools/cusMain'),點(diǎn)擊保存發(fā)送鏈接 并跳轉(zhuǎn)

tocustomQuery(){

this.$router.push('/reportTools/customQuery')

?? },

?

saveResource(){

console.log("當(dāng)前頁面表單的數(shù)據(jù)",this.form)

// sessionStorage.setItem("params",JSON.stringify(this.form))

console.log("sessionStorage中的數(shù)據(jù)",sessionStorage)

this.getcustomQuery()

this.$http.post("http://localhost:8080/reporttools/report-show/addReportShow",sessionStorage).then(

resp=>{

console.log(resp)

//this.$router.push('/reportTools/cusMain')

? ?? })

?? },

handleExceed(files,fileList) {

this.$message.warning(`當(dāng)前限制選擇 5 個文件椎木,本次選擇了 ${files.length}個文件,共選擇了 ${files.length+fileList.length}個文件`);

?? },

beforeRemove(file,fileList) {

returnthis.$confirm(`確定移除 ${file.name}博烂?`);

?? },

handleUploadError(error,file) {

console.log("文件上傳出錯:"+error)

?? },

//測試上傳文件(注意web的上下文)

handleBeforeUpload(file){

console.log("開始上傳香椎,上傳的文件為:"+file)

letformData=newFormData();

formData.append("multipartFiles",file);

axios({

method:'post',

url:'http://localhost:8080/file/upload',

data:formData,

headers: {'Content-Type':'multipart/form-data'}

}).then((res)=>{

console.log("文件上傳返回:"+res)

}).catch(error=>{

console.log("文件上傳異常:"+error)

? ?? })

?? },

? }

}

</script>

?

<stylescoped>

a{

text-decoration:none;

}

</style>

?

2.3.1上傳script全部代碼

主要是對前端做一些限制

handleExceed(files,fileList) {

this.$message.warning(`當(dāng)前限制選擇 5 個文件,本次選擇了 ${files.length}個文件禽篱,共選擇了 ${files.length+fileList.length}個文件`);

},

beforeRemove(file,fileList) {

returnthis.$confirm(`確定移除 ${file.name}畜伐?`);

},

handleUploadError(error,file) {

console.log("文件上傳出錯:"+error)

},

//測試上傳文件(注意web的上下文)

handleBeforeUpload(file){

console.log("開始上傳,上傳的文件為:"+file)

letformData=newFormData();

formData.append("multipartFiles",file);

axios({

method:'post',

url:'http://localhost:8080/file/upload',

data:formData,

headers: {'Content-Type':'multipart/form-data'}

}).then((res)=>{

console.log("文件上傳返回:"+res)

}).catch(error=>{

console.log("文件上傳異常:"+error)

? })

},

2.3.2在data的return里添加

uploadUrl:'file/upload',

fileList: [],

也就是在data層的 return里寫

data(){

return{

? ? uploadUrl:'http://localhost:8080/file/upload',

? ? ? ? fileList: [],

? ? }

}

就這樣前端就完成了

后端主要就是一個controller層

2.3.3Axios的引入

很重要的一個,因為我的寫法不一樣可能有不兼容的地方,有的vue不能這么寫,所以需要引入一下

直接引入就可以,在script里面,

不會就看我上面分享的

importaxiosfrom'axios'

3.后端

3.1后端全部代碼

packagecom.ciic.reporter.updownload.controller;

?

?

importorg.apache.tomcat.util.http.fileupload.IOUtils;

importorg.springframework.web.bind.annotation.*;

importorg.springframework.web.multipart.MultipartFile;

?

importjavax.servlet.http.HttpServletRequest;

importjavax.servlet.http.HttpServletResponse;

importjava.io.*;

importjava.nio.file.Files;

importjava.nio.file.Path;

importjava.nio.file.Paths;

?

?

@RestController

@RequestMapping("file")

publicclassCiicUpDownloadController{

privatefinalstaticStringrootPath="E:/attachment/";

?

@RequestMapping("/upload")

publicObjectuploadFile(@RequestParam("file")MultipartFile[]multipartFiles){

FilefileDir=newFile(rootPath);

if(!fileDir.exists()&&!fileDir.isDirectory()) {

fileDir.mkdirs();

? ? ?? }

try{

if(multipartFiles!=null&&multipartFiles.length>0) {

for(inti=0;i<multipartFiles.length;i++){

try{

//以原來的名稱命名,覆蓋掉舊的躺率,這里也可以使用UUID之類的方式命名烤礁,這里就沒有處理了

StringstoragePath=rootPath+multipartFiles[i].getOriginalFilename();

System.out.println("上傳的文件:"+multipartFiles[i].getName()+","+multipartFiles[i].getContentType()+","+multipartFiles[i].getOriginalFilename()

+",保存的路徑為:"+storagePath);

// 3種方法: 第1種

// ? ? ? ? ? ? ? ? ? ? ?? Streams.copy(multipartFiles[i].getInputStream(), new FileOutputStream(storagePath), true);

// 第2種

Pathpath=Paths.get(storagePath);

Files.write(path,multipartFiles[i].getBytes());

// 第3種

// multipartFiles[i].transferTo(new File(storagePath));

}catch(IOExceptione) {

e.printStackTrace();

? ? ? ? ? ? ? ? ?? }

? ? ? ? ? ? ?? }

? ? ? ? ?? }

?

}catch(Exceptione) {

e.printStackTrace();

? ? ?? }

//前端可以通過狀態(tài)碼肥照,判斷文件是否上傳成功

return"文件上傳成功";

?? }

?

?

/**

*

* @param fileName 文件名

* @param response

* @return

*/

@RequestMapping("/download")

publicObjectdownloadFile(@RequestParamStringfileName,HttpServletResponseresponse){

OutputStreamos=null;

InputStreamis=null;

try{

// 取得輸出流

os=response.getOutputStream();

// 清空輸出流

response.reset();

response.setContentType("application/x-download;charset=utf-8");

//Content-Disposition中指定的類型是文件的擴(kuò)展名,并且彈出的下載對話框中的文件類型圖片是按照文件的擴(kuò)展名顯示的勤众,點(diǎn)保存后舆绎,文件以filename的值命名,

// 保存類型以Content中設(shè)置的為準(zhǔn)们颜。注意:在設(shè)置Content-Disposition頭字段之前吕朵,一定要設(shè)置Content-Type頭字段。

//把文件名按UTF-8取出窥突,并按ISO8859-1編碼努溃,保證彈出窗口中的文件名中文不亂碼,中文不要太多阻问,最多支持17個中文梧税,因為header有150個字節(jié)限制。

response.setHeader("Content-Disposition","attachment;filename="+newString(fileName.getBytes("utf-8"),"ISO8859-1"));

//讀取流

Filef=newFile(rootPath+fileName);

is=newFileInputStream(f);

if(is==null) {

System.out.println("下載附件失敗称近,請檢查文件“"+fileName+"”是否存在");

return"下載附件失敗第队,請檢查文件“"+fileName+"”是否存在";

? ? ? ? ?? }

//復(fù)制

IOUtils.copy(is,response.getOutputStream());

response.getOutputStream().flush();

}catch(IOExceptione) {

return"下載附件失敗,error:"+e.getMessage();

? ? ?? }

//文件的關(guān)閉放在finally中

finally

? ? ?? {

try{

if(is!=null) {

is.close();

? ? ? ? ? ? ?? }

}catch(IOExceptione) {

e.printStackTrace();

? ? ? ? ?? }

try{

if(os!=null) {

os.close();

? ? ? ? ? ? ?? }

}catch(IOExceptione) {

e.printStackTrace();

? ? ? ? ?? }

? ? ?? }

//其實,這個返回什么都不重要

return"下載成功";

?? }

?

}

?

3.2后端定義一個class類

@RestController

@RequestMapping("file")

publicclassCiicUpDownloadController{

?

}

3.3后端定義一個上傳的路徑

privatefinalstaticStringrootPath="E:/attachment/";

3.3.1加上上面定義的類也就是

@RestController

@RequestMapping("file")

publicclassCiicUpDownloadController{

? ? privatefinalstaticStringrootPath="E:/attachment/";

}

3.4后端定義上傳方法

@RequestMapping("/upload")

publicObjectuploadFile(@RequestParam("file")MultipartFile[]multipartFiles){

FilefileDir=newFile(rootPath);

if(!fileDir.exists()&&!fileDir.isDirectory()) {

fileDir.mkdirs();

? ? ?? }

try{

if(multipartFiles!=null&&multipartFiles.length>0) {

for(inti=0;i<multipartFiles.length;i++){

try{

//以原來的名稱命名,覆蓋掉舊的刨秆,這里也可以使用UUID之類的方式命名凳谦,這里就沒有處理了

StringstoragePath=rootPath+multipartFiles[i].getOriginalFilename();

System.out.println("上傳的文件:"+multipartFiles[i].getName()+","+multipartFiles[i].getContentType()+","+multipartFiles[i].getOriginalFilename()

+",保存的路徑為:"+storagePath);

// 3種方法: 第1種

// ? ? ? ? ? ? ? ? ? ? ?? Streams.copy(multipartFiles[i].getInputStream(), new FileOutputStream(storagePath), true);

// 第2種

Pathpath=Paths.get(storagePath);

Files.write(path,multipartFiles[i].getBytes());

// 第3種

// multipartFiles[i].transferTo(new File(storagePath));

}catch(IOExceptione) {

e.printStackTrace();

? ? ? ? ? ? ? ? ?? }

? ? ? ? ? ? ?? }

? ? ? ? ?? }

?

}catch(Exceptione) {

e.printStackTrace();

? ? ?? }

//前端可以通過狀態(tài)碼衡未,判斷文件是否上傳成功

return"文件上傳成功";

?? }

?

3.4.3加上之前的路徑和類就是

@RestController

@RequestMapping("file")

publicclassCiicUpDownloadController{

privatefinalstaticStringrootPath="E:/attachment/";

?

@RequestMapping("/upload")

publicObjectuploadFile(@RequestParam("file")MultipartFile[]multipartFiles){

FilefileDir=newFile(rootPath);

if(!fileDir.exists()&&!fileDir.isDirectory()) {

fileDir.mkdirs();

? ? ?? }

try{

if(multipartFiles!=null&&multipartFiles.length>0) {

for(inti=0;i<multipartFiles.length;i++){

try{

//以原來的名稱命名,覆蓋掉舊的尸执,這里也可以使用UUID之類的方式命名家凯,這里就沒有處理了

StringstoragePath=rootPath+multipartFiles[i].getOriginalFilename();

System.out.println("上傳的文件:"+multipartFiles[i].getName()+","+multipartFiles[i].getContentType()+","+multipartFiles[i].getOriginalFilename()

+",保存的路徑為:"+storagePath);

// 3種方法: 第1種

// ? ? ? ? ? ? ? ? ? ? ?? Streams.copy(multipartFiles[i].getInputStream(), new FileOutputStream(storagePath), true);

// 第2種

Pathpath=Paths.get(storagePath);

Files.write(path,multipartFiles[i].getBytes());

// 第3種

// multipartFiles[i].transferTo(new File(storagePath));

}catch(IOExceptione) {

e.printStackTrace();

? ? ? ? ? ? ? ? ?? }

? ? ? ? ? ? ?? }

? ? ? ? ?? }

?

}catch(Exceptione) {

e.printStackTrace();

? ? ?? }

//前端可以通過狀態(tài)碼如失,判斷文件是否上傳成功

return"文件上傳成功";

?? }

}

3.5后端定義下載方法

/**

*

* @param fileName 文件名

* @param response

* @return

*/

@RequestMapping("/download")

publicObjectdownloadFile(@RequestParamStringfileName,HttpServletResponseresponse){

OutputStreamos=null;

InputStreamis=null;

try{

// 取得輸出流

os=response.getOutputStream();

// 清空輸出流

response.reset();

response.setContentType("application/x-download;charset=utf-8");

//Content-Disposition中指定的類型是文件的擴(kuò)展名绊诲,并且彈出的下載對話框中的文件類型圖片是按照文件的擴(kuò)展名顯示的,點(diǎn)保存后岖常,文件以filename的值命名驯镊,

// 保存類型以Content中設(shè)置的為準(zhǔn)。注意:在設(shè)置Content-Disposition頭字段之前竭鞍,一定要設(shè)置Content-Type頭字段板惑。

//把文件名按UTF-8取出,并按ISO8859-1編碼偎快,保證彈出窗口中的文件名中文不亂碼冯乘,中文不要太多,最多支持17個中文晒夹,因為header有150個字節(jié)限制裆馒。

response.setHeader("Content-Disposition","attachment;filename="+newString(fileName.getBytes("utf-8"),"ISO8859-1"));

//讀取流

Filef=newFile(rootPath+fileName);

is=newFileInputStream(f);

if(is==null) {

System.out.println("下載附件失敗,請檢查文件“"+fileName+"”是否存在");

return"下載附件失敗丐怯,請檢查文件“"+fileName+"”是否存在";

? ? ? ? ?? }

//復(fù)制

IOUtils.copy(is,response.getOutputStream());

response.getOutputStream().flush();

}catch(IOExceptione) {

return"下載附件失敗,error:"+e.getMessage();

? ? ?? }

//文件的關(guān)閉放在finally中

finally

? ? ?? {

try{

if(is!=null) {

is.close();

? ? ? ? ? ? ?? }

}catch(IOExceptione) {

e.printStackTrace();

? ? ? ? ?? }

try{

if(os!=null) {

os.close();

? ? ? ? ? ? ?? }

}catch(IOExceptione) {

e.printStackTrace();

? ? ? ? ?? }

? ? ?? }

//其實喷好,這個返回什么都不重要

return"下載成功";

?? }

3.5.1加上之前定義的路徑類和上傳方法就是

packagecom.ciic.reporter.updownload.controller;

?

?

importorg.apache.tomcat.util.http.fileupload.IOUtils;

importorg.springframework.web.bind.annotation.*;

importorg.springframework.web.multipart.MultipartFile;

?

importjavax.servlet.http.HttpServletRequest;

importjavax.servlet.http.HttpServletResponse;

importjava.io.*;

importjava.nio.file.Files;

importjava.nio.file.Path;

importjava.nio.file.Paths;

?

?

@RestController

@RequestMapping("file")

publicclassCiicUpDownloadController{

privatefinalstaticStringrootPath="E:/attachment/";

?

@RequestMapping("/upload")

publicObjectuploadFile(@RequestParam("file")MultipartFile[]multipartFiles){

FilefileDir=newFile(rootPath);

if(!fileDir.exists()&&!fileDir.isDirectory()) {

fileDir.mkdirs();

? ? ?? }

try{

if(multipartFiles!=null&&multipartFiles.length>0) {

for(inti=0;i<multipartFiles.length;i++){

try{

//以原來的名稱命名,覆蓋掉舊的,這里也可以使用UUID之類的方式命名读跷,這里就沒有處理了

StringstoragePath=rootPath+multipartFiles[i].getOriginalFilename();

System.out.println("上傳的文件:"+multipartFiles[i].getName()+","+multipartFiles[i].getContentType()+","+multipartFiles[i].getOriginalFilename()

+"梗搅,保存的路徑為:"+storagePath);

// 3種方法: 第1種

// ? ? ? ? ? ? ? ? ? ? ?? Streams.copy(multipartFiles[i].getInputStream(), new FileOutputStream(storagePath), true);

// 第2種

Pathpath=Paths.get(storagePath);

Files.write(path,multipartFiles[i].getBytes());

// 第3種

// multipartFiles[i].transferTo(new File(storagePath));

}catch(IOExceptione) {

e.printStackTrace();

? ? ? ? ? ? ? ? ?? }

? ? ? ? ? ? ?? }

? ? ? ? ?? }

?

}catch(Exceptione) {

e.printStackTrace();

? ? ?? }

//前端可以通過狀態(tài)碼,判斷文件是否上傳成功

return"文件上傳成功";

?? }

?

?

/**

*

* @param fileName 文件名

* @param response

* @return

*/

@RequestMapping("/download")

publicObjectdownloadFile(@RequestParamStringfileName,HttpServletResponseresponse){

OutputStreamos=null;

InputStreamis=null;

try{

// 取得輸出流

os=response.getOutputStream();

// 清空輸出流

response.reset();

response.setContentType("application/x-download;charset=utf-8");

//Content-Disposition中指定的類型是文件的擴(kuò)展名效览,并且彈出的下載對話框中的文件類型圖片是按照文件的擴(kuò)展名顯示的无切,點(diǎn)保存后,文件以filename的值命名丐枉,

// 保存類型以Content中設(shè)置的為準(zhǔn)哆键。注意:在設(shè)置Content-Disposition頭字段之前,一定要設(shè)置Content-Type頭字段瘦锹。

//把文件名按UTF-8取出籍嘹,并按ISO8859-1編碼,保證彈出窗口中的文件名中文不亂碼弯院,中文不要太多噩峦,最多支持17個中文,因為header有150個字節(jié)限制抽兆。

response.setHeader("Content-Disposition","attachment;filename="+newString(fileName.getBytes("utf-8"),"ISO8859-1"));

//讀取流

Filef=newFile(rootPath+fileName);

is=newFileInputStream(f);

if(is==null) {

System.out.println("下載附件失敗识补,請檢查文件“"+fileName+"”是否存在");

return"下載附件失敗,請檢查文件“"+fileName+"”是否存在";

? ? ? ? ?? }

//復(fù)制

IOUtils.copy(is,response.getOutputStream());

response.getOutputStream().flush();

}catch(IOExceptione) {

return"下載附件失敗,error:"+e.getMessage();

? ? ?? }

//文件的關(guān)閉放在finally中

finally

? ? ?? {

try{

if(is!=null) {

is.close();

? ? ? ? ? ? ?? }

}catch(IOExceptione) {

e.printStackTrace();

? ? ? ? ?? }

try{

if(os!=null) {

os.close();

? ? ? ? ? ? ?? }

}catch(IOExceptione) {

e.printStackTrace();

? ? ? ? ?? }

? ? ?? }

//其實辫红,這個返回什么都不重要

return"下載成功";

?? }

?

}

?

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末凭涂,一起剝皮案震驚了整個濱河市祝辣,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌切油,老刑警劉巖蝙斜,帶你破解...
    沈念sama閱讀 206,968評論 6 482
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異澎胡,居然都是意外死亡孕荠,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,601評論 2 382
  • 文/潘曉璐 我一進(jìn)店門攻谁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來稚伍,“玉大人,你說我怎么就攤上這事戚宦「鍪铮” “怎么了?”我有些...
    開封第一講書人閱讀 153,220評論 0 344
  • 文/不壞的土叔 我叫張陵受楼,是天一觀的道長垦搬。 經(jīng)常有香客問我,道長艳汽,這世上最難降的妖魔是什么猴贰? 我笑而不...
    開封第一講書人閱讀 55,416評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮河狐,結(jié)果婚禮上糟趾,老公的妹妹穿的比我還像新娘。我一直安慰自己甚牲,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,425評論 5 374
  • 文/花漫 我一把揭開白布蝶柿。 她就那樣靜靜地躺著丈钙,像睡著了一般。 火紅的嫁衣襯著肌膚如雪交汤。 梳的紋絲不亂的頭發(fā)上雏赦,一...
    開封第一講書人閱讀 49,144評論 1 285
  • 那天,我揣著相機(jī)與錄音芙扎,去河邊找鬼星岗。 笑死,一個胖子當(dāng)著我的面吹牛戒洼,可吹牛的內(nèi)容都是我干的俏橘。 我是一名探鬼主播,決...
    沈念sama閱讀 38,432評論 3 401
  • 文/蒼蘭香墨 我猛地睜開眼圈浇,長吁一口氣:“原來是場噩夢啊……” “哼寥掐!你這毒婦竟也來了靴寂?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,088評論 0 261
  • 序言:老撾萬榮一對情侶失蹤召耘,失蹤者是張志新(化名)和其女友劉穎百炬,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體污它,經(jīng)...
    沈念sama閱讀 43,586評論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡剖踊,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,028評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了衫贬。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片德澈。...
    茶點(diǎn)故事閱讀 38,137評論 1 334
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖祥山,靈堂內(nèi)的尸體忽然破棺而出圃验,到底是詐尸還是另有隱情,我是刑警寧澤缝呕,帶...
    沈念sama閱讀 33,783評論 4 324
  • 正文 年R本政府宣布澳窑,位于F島的核電站,受9級特大地震影響供常,放射性物質(zhì)發(fā)生泄漏摊聋。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,343評論 3 307
  • 文/蒙蒙 一栈暇、第九天 我趴在偏房一處隱蔽的房頂上張望麻裁。 院中可真熱鬧,春花似錦源祈、人聲如沸煎源。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,333評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽手销。三九已至,卻和暖如春图张,著一層夾襖步出監(jiān)牢的瞬間锋拖,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,559評論 1 262
  • 我被黑心中介騙來泰國打工祸轮, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留兽埃,地道東北人。 一個月前我還...
    沈念sama閱讀 45,595評論 2 355
  • 正文 我出身青樓适袜,卻偏偏與公主長得像柄错,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,901評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 以ASP.NET Core WebAPI作后端API鄙陡,用Vue構(gòu)建前端頁面冕房,用Axios從前端訪問后端API ,包...
    jianshu1212閱讀 807評論 0 0
  • javaweb上傳文件 上傳文件的jsp中的部分 上傳文件同樣可以使用form表單向后端發(fā)請求,也可以使用 aja...
    jianshu1212閱讀 227評論 0 0
  • 久違的晴天趁矾,家長會耙册。 家長大會開好到教室時,離放學(xué)已經(jīng)沒多少時間了毫捣。班主任說已經(jīng)安排了三個家長分享經(jīng)驗详拙。 放學(xué)鈴聲...
    飄雪兒5閱讀 7,495評論 16 22
  • 今天感恩節(jié)哎,感謝一直在我身邊的親朋好友蔓同。感恩相遇饶辙!感恩不離不棄。 中午開了第一次的黨會斑粱,身份的轉(zhuǎn)變要...
    迷月閃星情閱讀 10,551評論 0 11
  • 可愛進(jìn)取弃揽,孤獨(dú)成精。努力飛翔则北,天堂翱翔矿微。戰(zhàn)爭美好,孤獨(dú)進(jìn)取尚揣。膽大飛翔涌矢,成就輝煌。努力進(jìn)取快骗,遙望娜庇,和諧家園》嚼海可愛游走...
    趙原野閱讀 2,716評論 1 1