SSM框架實現附帶信息的文件上傳&下載
SSM框架實現附帶信息的文件上傳&下載
目錄
技術概述
? 在進行團隊開發時,分配到了資源和作業部分的后端相關內容,需要實現文件的上傳和下載。但是由于各個文件保存路徑不相同,以及存在需要附帶信息保存的情況,如提交作業時同時有附件、正文內容以及附帶學生id與班級id,教師上傳資源時要傳遞班級id與教師id等。在同時上傳文件和傳遞信息時,本來使用form表單傳遞即可,但是前端用了vue框架,加上除了表單中填寫的信息還要附帶其他信息,最后找到了form-data傳遞的辦法。
技術詳述

- 我們使用一個類封裝了需要的信息和文件
public class ResourceDTO {
private int id;
private String resourceName;
private int type;
private int downloads;
private String filePath;
private int teacherId;
private int clazzId;
private MultipartFile file;
......
其他字段用于保存信息,file用來存文件。
- 準備好依賴
pom.xml
<!-- 文件上傳 -->
<dependency>
<groupId>commons-fileupload</groupId>
<artifactId>commons-fileupload</artifactId>
<version>1.3</version>
</dependency>
springmvc.xml中
<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="#{1024*1024*20}"/>
<property name="defaultEncoding" value="utf-8"/>
</bean>
- 在Controller中,接受前端數據并存儲
@RequestMapping("upload")
@ResponseBody
public ResponseVO upload(@ModelAttribute ResourceDTO requestResource, HttpServletRequest request) {
try {
MultipartFile file = requestResource.getFile();
String originalFileName = file.getOriginalFilename();
String fileUrl = "/WEB-INF/resource/" + requestResource.getTeacherId() +"/" + requestResource.getClazzId() + "/" + originalFileName;//這是路徑,可以自定義
//獲取路徑
fileUrl = request.getSession().getServletContext().getRealPath(fileUrl);
//向url地址存儲文件
FileUtil.writeFileToUrl(file, fileUrl);
//接下來就是將requestResource的數據存到數據庫中,這里就不放了
......
}
catch(Exception e){
e.printStackTrace();
}
......
FileUtil的代碼如下:
import org.springframework.web.multipart.MultipartFile;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Date;
public class FileUtil {
public static void writeFileToUrl(MultipartFile file, String fileUrl) throws IOException {
File file1 = new File(fileUrl);
if (!file1.getParentFile().exists()) {
file1.getParentFile().mkdirs();
}
FileOutputStream fos = new FileOutputStream(file1);
fos.write(file.getBytes());
fos.flush();
fos.close();
}
}
- 可以寫個表單測試一下
<form action = "upload" method="post" enctype="multipart/form-data">
<input type="file" name = "file">
<input type="submit" value="上傳文件">
</form>
- 下載我采用了簡單的數據流下載
@RequestMapping(value = "/resource/download")
public void download(HttpServletRequest request, HttpServletResponse response ,@RequestParam("id") int id){
try {
Resource requestResource = resourceService.findById(id);
String filePath = requestResource.getFilePath();
File file = new File(filePath);//如果文件存在的話
resourceService.modifyDownload(requestResource.getId());
if (file.exists()) {//獲取輸入流
InputStream bis = new BufferedInputStream(new FileInputStream(file));//假如以中文名下載的話
String filename = requestResource.getResourceName() ;
filename = URLEncoder.encode(filename, "UTF-8" );//設置文件下載頭
response.addHeader("Content-Disposition", "attachment;filename=" + filename);
response.setContentType ( "multipart/form-data" );
BufferedOutputStream out = new BufferedOutputStream(response.getOutputStream());int len = 0;
while ((len = bis.read()) != -1) {
out.write(len);
}
out.close();
}
} catch (IOException ioException) {
ioException.printStackTrace();
}
}
技術使用中遇到的問題和解決過程
我們遇到的問題是:前端使用了vue框架,上傳文件時我們不知道如何進行附帶信息的傳遞。
解決:翻了很多博客,最后使用form-data來進行數據與文件的傳遞,與負責相關前端的組長同志交流測試后完成,確認可用。
ps:以下前端代碼是由我們偉大的組長完成的
表單部分:
<div id="divForm">
<el-form :model="publishForm" ref="publishForm" label-position="top">
<el-form-item label="資源信息" class="label">
<i class="el-icon-star-on">選擇分組</i>
<br>
<el-select v-model="typeValue" placeholder="課程資源">
<el-option
v-for="item in typeOptions"
:key="item.value"
:label="item.label"
:value="item.value">
</el-option>
</el-select>
</el-form-item>
<el-form-item label="資源內容" class="label">
<i class="el-icon-star-on">上傳文件</i>
<br/>
<input class="file" name="file" type="file" @change="select"/>
<p id="p">提示:單個文件不超過20MB</p>
</el-form-item>
<el-form-item>
<el-button id="cancel" type="primary" plain size="mini" @click="cancelClick">取消</el-button>
<el-popover
placement="top"
width="160"
v-model="visible">
<p>確定發布該資源嗎?</p>
<div style="text-align: right; margin: 0">
<el-button size="mini" type="text" @click="visible = false">取消</el-button>
<el-button type="primary" size="mini" @click="publishClick">確定</el-button>
</div>
<el-button slot="reference" id="publish" class="button" type="primary" plain size="mini">發布</el-button>
</el-popover>
</el-form-item>
</el-form>
</div>
以下是數據處理
publishClick() {//確定上傳
let param = new FormData() // 創建form對象
param.append('file', this.file, this.file.name) // 通過append向form對象添加數據
param.append('teacherId', this.tId)
param.append('clazzId',this.clazzValue)
param.append('type',this.typeValue)// 添加form表單中其他數據
// withCredentials: true 使得后臺可以接收表單數據 跨域請求
const instance = this.$axios.create({
withCredentials: true,
headers:{
'Content-type': 'application/json;charset=UTF-8',
'Authorization': localStorage.getItem('token')
}
})
// url為后臺接口
instance.post('http://1.15.149.222:8080/coursewebsite/teacher/resource/upload', param)
.then((response) => {
console.log(response.data)
if (response.data.code==='200') {
alert('上傳成功')
this.$router.push('/teacher/source/study')
this.$router.go(0)
}
}) // 成功返回信息 調用函數 函數需自己定義,此處后面省略
.catch((error) => {
console.log(error) //請求失敗返回的數據
})
}
總結
1.準備好依賴與封裝好的類
2.寫好Controller的處理
3.寫好前端的處理
參考鏈接
作者:fujiangfer
-------------------------------------------
個性簽名:沒有
如果覺得這篇文章對你有小小的幫助的話,記得在右下角點個“推薦”哦,博主在此感謝!
萬水千山總是情,打賞一分行不行(っ??ω??)っ???!

浙公網安備 33010602011771號