仵航说 前后端分离,文件上传下载(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>基本信息设置</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">点击上传</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;表示当前用户名,

&#123;&nbsp;{TITLE&#125;&nbsp;&#125;表示表头,&#123;&nbsp;{DATA&#125;&nbsp;&#125;表示数据行,&#123;&nbsp;{FOOTER&#125;&nbsp;&#125;表示页脚区域。

     导出的内容不可改动,页眉页脚区域可以自由编辑。

</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="是否导出"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("上个页面传来的是",sessionStorage)

// this.handleUUIDv1()

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

console.log("页面刷新后新产生的uuid是",this.form.code)

  },

watch:{

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

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

   }

  },

methods: {

//使用uuid

// handleUUIDv1() {

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

// },

//点击多选按钮true和false变成1或者2

reset(form){

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

   },

//获取上个页面传来的数据

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("上个页面传来的是",sessionStorage)

   },

// this.$router.push('/reportTools/cusMain'),点击保存发送链接 并跳转

tocustomQuery(){

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

   },

saveResource(){

console.log("当前页面表单的数据",this.form)

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

console.log("sessionStorage中的数据",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(`当前限制选择 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">点击上传</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">点击上传</el-button>

</el-upload>

2.2.3下载代码

下载代码就是一个a标签

<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("上个页面传来的是",sessionStorage)

// this.handleUUIDv1()

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

console.log("页面刷新后新产生的uuid是",this.form.code)

  },

watch:{

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

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

   }

  },

methods: {

//使用uuid

// handleUUIDv1() {

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

// },

//点击多选按钮true和false变成1或者2

reset(form){

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

   },

//获取上个页面传来的数据

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("上个页面传来的是",sessionStorage)

   },

// this.$router.push('/reportTools/cusMain'),点击保存发送链接 并跳转

tocustomQuery(){

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

   },

saveResource(){

console.log("当前页面表单的数据",this.form)

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

console.log("sessionStorage中的数据",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(`当前限制选择 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(`当前限制选择 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();

       }

//前端可以通过状态码,判断文件是否上传成功

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中指定的类型是文件的扩展名,并且弹出的下载对话框中的文件类型图片是按照文件的扩展名显示的,点保存后,文件以filename的值命名,

// 保存类型以Content中设置的为准。注意:在设置Content-Disposition头字段之前,一定要设置Content-Type头字段。

//把文件名按UTF-8取出,并按ISO8859-1编码,保证弹出窗口中的文件名中文不乱码,中文不要太多,最多支持17个中文,因为header有150个字节限制。

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+"”是否存在";

           }

//复制

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

response.getOutputStream().flush();

}catch(IOExceptione) {

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

       }

//文件的关闭放在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();

       }

//前端可以通过状态码,判断文件是否上传成功

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();

       }

//前端可以通过状态码,判断文件是否上传成功

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中指定的类型是文件的扩展名,并且弹出的下载对话框中的文件类型图片是按照文件的扩展名显示的,点保存后,文件以filename的值命名,

// 保存类型以Content中设置的为准。注意:在设置Content-Disposition头字段之前,一定要设置Content-Type头字段。

//把文件名按UTF-8取出,并按ISO8859-1编码,保证弹出窗口中的文件名中文不乱码,中文不要太多,最多支持17个中文,因为header有150个字节限制。

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+"”是否存在";

           }

//复制

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

response.getOutputStream().flush();

}catch(IOExceptione) {

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

       }

//文件的关闭放在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();

       }

//前端可以通过状态码,判断文件是否上传成功

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中指定的类型是文件的扩展名,并且弹出的下载对话框中的文件类型图片是按照文件的扩展名显示的,点保存后,文件以filename的值命名,

// 保存类型以Content中设置的为准。注意:在设置Content-Disposition头字段之前,一定要设置Content-Type头字段。

//把文件名按UTF-8取出,并按ISO8859-1编码,保证弹出窗口中的文件名中文不乱码,中文不要太多,最多支持17个中文,因为header有150个字节限制。

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+"”是否存在";

           }

//复制

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

response.getOutputStream().flush();

}catch(IOExceptione) {

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

       }

//文件的关闭放在finally中

finally

       {

try{

if(is!=null) {

is.close();

               }

}catch(IOExceptione) {

e.printStackTrace();

           }

try{

if(os!=null) {

os.close();

               }

}catch(IOExceptione) {

e.printStackTrace();

           }

       }

//其实,这个返回什么都不重要

return"下载成功";

   }

}

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,817评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,329评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,354评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,498评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,600评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,829评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,979评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,722评论 0 266
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,189评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,519评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,654评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,329评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,940评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,762评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,993评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,382评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,543评论 2 349

推荐阅读更多精彩内容

  • 以ASP.NET Core WebAPI作后端API,用Vue构建前端页面,用Axios从前端访问后端API ,包...
    jianshu1212阅读 813评论 0 0
  • javaweb上传文件 上传文件的jsp中的部分 上传文件同样可以使用form表单向后端发请求,也可以使用 aja...
    jianshu1212阅读 233评论 0 0
  • 久违的晴天,家长会。 家长大会开好到教室时,离放学已经没多少时间了。班主任说已经安排了三个家长分享经验。 放学铃声...
    飘雪儿5阅读 7,513评论 16 22
  • 今天感恩节哎,感谢一直在我身边的亲朋好友。感恩相遇!感恩不离不弃。 中午开了第一次的党会,身份的转变要...
    迷月闪星情阅读 10,559评论 0 11
  • 可爱进取,孤独成精。努力飞翔,天堂翱翔。战争美好,孤独进取。胆大飞翔,成就辉煌。努力进取,遥望,和谐家园。可爱游走...
    赵原野阅读 2,723评论 1 1