Springmvc模式上傳和下載與enctype對(duì)比
一般表單數(shù)據(jù)分為兩類
<form method="post" action="${pageContext.request.contextPath}/upload" enctype="multipart/form-data">
enctype帶文件上傳的表單和不帶enctype的傳統(tǒng)表單,這兩種提交的數(shù)據(jù)有著不同的樣式,并且上傳文件只能使用enctype。
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//服務(wù)器存儲(chǔ)文件的地址,需自己定義
String savepath = this.getServletContext().getRealPath("/upload");
System.out.println(savepath);
//如果文件不存在,需要先進(jìn)行判斷,并創(chuàng)建,否則會(huì)出現(xiàn)空文件報(bào)錯(cuò)
File file=new File(savepath);
if(!file.exists()){
file.mkdir();
}
//工具類commons-fileupload包創(chuàng)建工廠對(duì)象
DiskFileItemFactory itemFactory=new DiskFileItemFactory();
ServletFileUpload upload=new ServletFileUpload(itemFactory);
//判斷是不是傳統(tǒng)表單
if(!ServletFileUpload.isMultipartContent(req)){
System.out.println("是傳統(tǒng)的表單 沒有上傳功能");
return;
}
try {
//表單的各項(xiàng)數(shù)據(jù)對(duì)象,封裝成集合
List<FileItem> list = upload.parseRequest(req);
for(FileItem item:list){
//是普通的表單數(shù)據(jù)
if(item.isFormField()){
String fieldName = item.getFieldName();
String value = item.getString("utf-8");
System.out.println(fieldName+" "+value);
}else {
String filename = item.getName();//上傳的文件名字
if(filename==null||filename.trim().equals("")){
// 當(dāng)前上傳的文件為空
continue;
}
System.out.println(filename);
//得到文件的名字
filename = filename.substring(filename.lastIndexOf("\\")+1);
InputStream in = item.getInputStream();
OutputStream out=new FileOutputStream(savepath+"\\"+filename);
byte[] buf=new byte[1024];
int len=0;
while((len=in.read(buf))>0){
out.write(buf,0,len);
}
in.close();
out.close();
}
}
} catch (FileUploadException e) {
e.printStackTrace();
}
req.getRequestDispatcher("/downloadlist").forward(req,resp);
}
上傳文件的大致上,是將提交的文件轉(zhuǎn)存到服務(wù)器端的一個(gè)文件目錄下。然后轉(zhuǎn)發(fā)到展示頁面供選擇。
下載文件的一些設(shè)置
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
req.setCharacterEncoding("utf-8");
resp.setContentType("text/html;charset=utf-8");
//獲取前臺(tái)文件所展示的文件名稱和存儲(chǔ)目錄下的名稱要一致,方便寫參數(shù)下載。
String fileName= req.getParameter("file");
//先獲取上傳目錄路徑
String basePath = getServletContext().getRealPath("/upload");
//如果文件名是中文,需要進(jìn)行url編碼,此操作是為了避免不同瀏覽器的下載頁面下文件亂碼的情況
String agent = req.getHeader("User-Agent");
String filenameEncoder = "";
if (agent.contains("MSIE")) {
// IE瀏覽器
filenameEncoder = URLEncoder.encode(fileName, "utf-8");
filenameEncoder = filenameEncoder.replace("+", " ");
} else if (agent.contains("Firefox")) {
// 火狐瀏覽器
BASE64Encoder base64Encoder = new BASE64Encoder();
filenameEncoder = "=?utf-8?B?"
+ base64Encoder.encode(fileName.getBytes("utf-8")) + "?=";
} else {
// 其它瀏覽器
filenameEncoder = URLEncoder.encode(fileName, "utf-8");
}
//設(shè)置下載的響應(yīng)頭
resp.setHeader("content-disposition", "attachment;fileName="+filenameEncoder);//此filenameEncoder必須經(jīng)過轉(zhuǎn)碼處理
//獲取一個(gè)文件輸入流
InputStream is = new FileInputStream(new File(basePath,fileName));
//獲取response字節(jié)流
OutputStream out = resp.getOutputStream();
byte[] b= new byte[1024];
int len =-1;
while((len=is.read(b))!=-1){
out.write(b,0,len);
}
//關(guān)閉流
out.close();
is.close();
}
下載的設(shè)置上需要注意文件名的一些亂碼問題,最主要的是區(qū)別于不同瀏覽器下的一些差異。需要對(duì)文件名轉(zhuǎn)碼處理。
還需要提前設(shè)置對(duì)瀏覽器的響應(yīng)頭,告知瀏覽器是一個(gè)文件。
resp.setHeader("content-disposition", "attachment;fileName="+filenameEncoder);
接觸了springmvc模式后,對(duì)上面的上傳與下載進(jìn)行優(yōu)化,
此處上傳的功能依舊是采用表格上傳。文件格式依舊是
<form action="${pageContext.request.contextPath}/upload" method="post" enctype="multipart/form-data">
后臺(tái)則是
@RequestMapping("/upload")
public String upload(MultipartFile file,String userName,HttpServletRequest request) throws IOException {
String filename = file.getOriginalFilename();
String suffix = filename.substring(filename.lastIndexOf("."));
if(suffix.equalsIgnoreCase(".jpg")){
String uuid = UUID.randomUUID().toString();
//FileUtils.copyInputStreamToFile(file.getInputStream(),new File("E://"+uuid+suffix));
file.transferTo(new File("D://"+System.currentTimeMillis()+suffix));//位置存儲(chǔ)在硬盤上
// file.transferTo(new File(request.getServletContext().getRealPath("/")+"static/userImages/"+file));
// 存儲(chǔ)在項(xiàng)目里的目錄下
request.setAttribute("result","上傳成功");
return "/result.jsp";
}else{
request.setAttribute("result","上傳失敗");
return "/result.jsp";
}
}
相比之前的傳統(tǒng)式上傳,springmvc模式下封裝了許多繁瑣的過程,通過transferTo即可實(shí)現(xiàn)一些相應(yīng)的操作
而下載也是相應(yīng)的簡化了許多
@RequestMapping("/download")
public void download(String filename, HttpServletResponse response, HttpServletRequest request) throws IOException {
response.setHeader("content-disposition","attachment;filename="+filename);
ServletOutputStream outputStream = response.getOutputStream();
String path = request.getServletContext().getRealPath("images");
File file = new File(path,filename);
byte[] bytes = FileUtils.readFileToByteArray(file);
outputStream.write(bytes);
outputStream.close();
}
一般框架會(huì)省去許多重復(fù)性的工作,但底層的基本原理還是要清楚過程
以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
SpringBoot配置嵌入式Servlet容器和使用外置Servlet容器的教程圖解
這篇文章主要介紹了SpringBoot配置嵌入式Servlet容器和使用外置Servlet容器的教程,本文通過圖文并茂的形式給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07
springboot2.5.2與 flowable6.6.0整合流程引擎應(yīng)用分析
這篇文章主要介紹了springboot2.5.2與 flowable6.6.0整合流程引擎應(yīng)用分析,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-07-07
Java中StringUtils工具類的一些用法實(shí)例
這篇文章主要介紹了Java中StringUtils工具類的一些用法實(shí)例,本文著重講解了isEmpty和isBlank方法的使用,另外也講解了trim、strip等方法的使用實(shí)例,需要的朋友可以參考下2015-06-06
總結(jié)一下關(guān)于在Java8中使用stream流踩過的一些坑
java8新增了stream流式處理,對(duì)于list的各種操作處理提供了好多方法 ,用過的都知道,方便極了.比如篩選、排序、合并、類型轉(zhuǎn)換等等.以下是我實(shí)際工作中踩過的坑,記錄下避免大家踩坑,需要的朋友可以參考下2021-06-06
Spring boot調(diào)用Oracle存儲(chǔ)過程的兩種方式及完整代碼
這篇文章主要給大家介紹了關(guān)于Spring boot調(diào)用Oracle存儲(chǔ)過程的兩種方式及完整代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2020-08-08
SpringAOP事務(wù)配置語法及實(shí)現(xiàn)過程詳解
這篇文章主要介紹了SpringAOP事務(wù)配置語法及實(shí)現(xiàn)過程詳解,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-06-06
java8 forEach結(jié)合Lambda表達(dá)式遍歷 List操作
這篇文章主要介紹了java8 forEach結(jié)合Lambda表達(dá)式遍歷 List操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-09-09
Jenkins自動(dòng)構(gòu)建部署項(xiàng)目到遠(yuǎn)程服務(wù)器上的方法步驟
這篇文章主要介紹了Jenkins自動(dòng)構(gòu)建部署項(xiàng)目到遠(yuǎn)程服務(wù)器上的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01

