SpringMVC文件上傳中要解決的問題大匯總
SpringMVC文件上傳中要解決的問題
一、中文文件名編碼問題
通過過濾器解決
二、文件位置存儲(chǔ)問題
放在當(dāng)前項(xiàng)目下,作為靜態(tài)資源,這樣可以通過URL訪問。
package com.lanson.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import java.io.File; import java.io.IOException; /** * @Author: Lansonli * @Description: MircoMessage:Mark_7001 */ @Controller public class FileUploadController { @ResponseBody @RequestMapping("fileUpload.do") public String fileUpload(MultipartFile headPhoto, HttpServletRequest req) throws IOException { // 指定文件存儲(chǔ)目錄為我們項(xiàng)目部署環(huán)境下的upload目錄 String realPath = req.getServletContext().getRealPath("/upload"); File dir = new File(realPath); // 如果不存在則創(chuàng)建目錄 if(!dir.exists()){ dir.mkdirs(); } // 獲取文件名 String originalFilename = headPhoto.getOriginalFilename(); // 文件存儲(chǔ)位置 File file =new File(dir,originalFilename); // 文件保存 headPhoto.transferTo(file); return "OK"; } }
在SpringMVC中配置靜態(tài)資源放行
<mvc:resources mapping="/upload/**" location="/upload/"></mvc:resources>
三、文件名沖突問題
使用UUID對(duì)文件名進(jìn)行重命名。
package com.lanson.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import java.io.File; import java.io.IOException; import java.util.UUID; /** * @Author: Lansonli * @Description: MircoMessage:Mark_7001 */ @Controller public class FileUploadController { @ResponseBody @RequestMapping("fileUpload.do") public String fileUpload(MultipartFile headPhoto, HttpServletRequest req) throws IOException { // 指定文件存儲(chǔ)目錄為我們項(xiàng)目部署環(huán)境下的upload目錄 String realPath = req.getServletContext().getRealPath("/upload"); File dir = new File(realPath); // 如果不存在則創(chuàng)建目錄 if(!dir.exists()){ dir.mkdirs(); } // 獲取文件名 String originalFilename = headPhoto.getOriginalFilename(); // 避免文件名沖突,使用UUID替換文件名 String uuid = UUID.randomUUID().toString(); // 獲取拓展名 String extendsName = originalFilename.substring(originalFilename.lastIndexOf(".")); // 新的文件名 String newFileName=uuid.concat(extendsName); // 文件存儲(chǔ)位置 File file =new File(dir,newFileName); // 文件保存 headPhoto.transferTo(file); return "OK"; } }
四、控制文件類型和大小
package com.lanson.controller; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.UUID; /** * @Author: Lansonli * @Description: MircoMessage:Mark_7001 */ @Controller public class FileUploadController { @ResponseBody @RequestMapping("fileUpload.do") public Map<String,String> fileUpload(MultipartFile headPhoto, HttpServletRequest req) throws IOException { Map<String,String> map=new HashMap<>(); // 控制文件大小 if(headPhoto.getSize()>1024*1024*5){ map.put("message", "文件大小不能超過5M"); return map; } // 指定文件存儲(chǔ)目錄為我們項(xiàng)目部署環(huán)境下的upload目錄 String realPath = req.getServletContext().getRealPath("/upload"); File dir = new File(realPath); // 如果不存在則創(chuàng)建目錄 if(!dir.exists()){ dir.mkdirs(); } // 獲取文件名 String originalFilename = headPhoto.getOriginalFilename(); // 避免文件名沖突,使用UUID替換文件名 String uuid = UUID.randomUUID().toString(); // 獲取拓展名 String extendsName = originalFilename.substring(originalFilename.lastIndexOf(".")); // 控制文件類型 if(!extendsName.equals(".jpg")){ map.put("message", "文件類型必須是.jpg"); return map; } // 新的文件名 String newFileName=uuid.concat(extendsName); // 文件存儲(chǔ)位置 File file =new File(dir,newFileName); // 文件保存 headPhoto.transferTo(file); // 上傳成功之后,把文件的名字和文件的類型返回給瀏覽器 map.put("message", "上傳成功"); map.put("newFileName", newFileName); map.put("filetype", headPhoto.getContentType()); return map; } }
通過文件上傳解析組件控制。
但是會(huì)出現(xiàn)異常,后期可以可以配置一個(gè)異常解析器解決。
<!--文件上傳解析組件 id必須為multipartResolver springmvc默認(rèn)使用該id找該組件 --> <bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver"> <!--設(shè)置文件大小--> <property name="maxUploadSizePerFile" value="10"></property> </bean>
五、上傳圖片回顯問題
后天已經(jīng)將圖片的文件名響應(yīng)給瀏覽器。
前端代碼
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> <script type="text/javascript" src="js/jquery.min.js"></script> <script type="text/javascript"> $(function(){ $("#uploadFile").click(function(){ // 獲取要上傳的文件 var photoFile =$("#photo")[0].files[0] if(photoFile==undefined){ alert("您還未選中文件") return; } // 將文件裝入FormData對(duì)象 var formData =new FormData(); formData.append("headPhoto",photoFile) // ajax向后臺(tái)發(fā)送文件 $.ajax({ type:"post", data:formData, url:"fileUpload.do", processData:false, contentType:false, success:function(result){ // 接收后臺(tái)響應(yīng)的信息 alert(result.message) // 圖片回顯 $("#headImg").attr("src","upload/"+result.newFileName); } }) }) }) </script> </head> <body> <form action="addPlayer" method="get"> <p>賬號(hào)<input type="text" name="name"></p> <p>密碼<input type="text" name="password"></p> <p>昵稱<input type="text" name="nickname"></p> <p>頭像: <br/> <input id="photo" type="file"> <br/> <img id="headImg" style="width: 200px;height: 200px" alt="你還未上傳圖片"> <br/> <a id="uploadFile" href="javascript:void(0)" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >立即上傳</a> </p> <p><input type="submit" value="注冊(cè)"></p> </form> </body> </html>
六、進(jìn)度條問題
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> <style> .progress { width: 200px; height: 10px; border: 1px solid #ccc; border-radius: 10px; margin: 10px 0px; overflow: hidden; } /* 初始狀態(tài)設(shè)置進(jìn)度條寬度為0px */ .progress > div { width: 0px; height: 100%; background-color: yellowgreen; transition: all .3s ease; } </style> <script type="text/javascript" src="js/jquery.min.js"></script> <script type="text/javascript"> $(function(){ $("#uploadFile").click(function(){ // 獲取要上傳的文件 var photoFile =$("#photo")[0].files[0] if(photoFile==undefined){ alert("您還未選中文件") return; } // 將文件裝入FormData對(duì)象 var formData =new FormData(); formData.append("headPhoto",photoFile) // ajax向后臺(tái)發(fā)送文件 $.ajax({ type:"post", data:formData, url:"fileUpload.do", processData:false, contentType:false, success:function(result){ // 接收后臺(tái)響應(yīng)的信息 alert(result.message) // 圖片回顯 $("#headImg").attr("src","upload/"+result.newFileName); }, xhr: function() { var xhr = new XMLHttpRequest(); //使用XMLHttpRequest.upload監(jiān)聽上傳過程,注冊(cè)progress事件,打印回調(diào)函數(shù)中的event事件 xhr.upload.addEventListener('progress', function (e) { //loaded代表上傳了多少 //total代表總數(shù)為多少 var progressRate = (e.loaded / e.total) * 100 + '%'; //通過設(shè)置進(jìn)度條的寬度達(dá)到效果 $('.progress > div').css('width', progressRate); }) return xhr; } }) }) }) </script> </head> <body> <form action="addPlayer" method="get"> <p>賬號(hào)<input type="text" name="name"></p> <p>密碼<input type="text" name="password"></p> <p>昵稱<input type="text" name="nickname"></p> <p>頭像: <br/> <input id="photo" type="file"> <%--圖片回顯--%> <br/> <img id="headImg" style="width: 200px;height: 200px" alt="你還未上傳圖片"> <br/> <%--進(jìn)度條--%> <div class="progress"> <div></div> </div> <a id="uploadFile" href="javascript:void(0)" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >立即上傳</a> </p> <p><input type="submit" value="注冊(cè)"></p> </form> </body> </html>
七、單獨(dú)準(zhǔn)備文件存儲(chǔ)服務(wù)器
分服務(wù)器上傳作用
- 數(shù)據(jù)庫服務(wù)器:運(yùn)行我們的數(shù)據(jù)庫
- 緩存和消息服務(wù)器:負(fù)責(zé)處理大并發(fā)訪問的緩存和消息
- 文件服務(wù)器:負(fù)責(zé)存儲(chǔ)用戶上傳文件的服務(wù)器。
- 應(yīng)用服務(wù)器:負(fù)責(zé)部署我們的應(yīng)用
在實(shí)際開發(fā)中,我們會(huì)有很多處理不同功能的服務(wù)器。(注意:此處說的不是服務(wù)器集群)
總結(jié):分服務(wù)器處理的目的是讓服務(wù)器各司其職,從而提高我們項(xiàng)目的運(yùn)行效率。
分服務(wù)器工作示意圖
單獨(dú)解壓一個(gè)Tomcat作為文件服務(wù)器
設(shè)置遠(yuǎn)程服務(wù)器端口號(hào)
遠(yuǎn)程服務(wù)器中設(shè)置非只讀
webapps下創(chuàng)建一個(gè)upload目錄
啟動(dòng)測(cè)試
項(xiàng)目中導(dǎo)入依賴
<dependency> <groupId>com.sun.jersey</groupId> <artifactId>jersey-client</artifactId> <version>1.19</version> </dependency>
controller代碼
package com.lanson.controller; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.WebResource; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.ResponseBody; import org.springframework.web.multipart.MultipartFile; import javax.servlet.http.HttpServletRequest; import java.io.File; import java.io.IOException; import java.util.HashMap; import java.util.Map; import java.util.UUID; /** * @Author: Lansonli * @Description: MircoMessage:Mark_7001 */ @Controller public class FileUploadController { // 文件存儲(chǔ)位置 private final static String FILESERVER="http://192.168.8.109:8090/upload/"; @ResponseBody @RequestMapping("fileUpload.do") public Map<String,String> fileUpload(MultipartFile headPhoto, HttpServletRequest req) throws IOException { Map<String,String> map=new HashMap<>(); // 獲取文件名 String originalFilename = headPhoto.getOriginalFilename(); // 避免文件名沖突,使用UUID替換文件名 String uuid = UUID.randomUUID().toString(); // 獲取拓展名 String extendsName = originalFilename.substring(originalFilename.lastIndexOf(".")); // 新的文件名 String newFileName=uuid.concat(extendsName); // 創(chuàng)建 sun公司提供的jersey包中的client對(duì)象 Client client=Client.create(); WebResource resource = client.resource(FILESERVER + newFileName); // 文件保存到另一個(gè)服務(wù)器上去了 resource.put(String.class, headPhoto.getBytes()); // 上傳成功之后,把文件的名字和文件的類型返回給瀏覽器 map.put("message", "上傳成功"); map.put("newFileName",newFileName); map.put("filetype", headPhoto.getContentType()); return map; } }
頁面代碼
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> <style> .progress { width: 200px; height: 10px; border: 1px solid #ccc; border-radius: 10px; margin: 10px 0px; overflow: hidden; } /* 初始狀態(tài)設(shè)置進(jìn)度條寬度為0px */ .progress > div { width: 0px; height: 100%; background-color: yellowgreen; transition: all .3s ease; } </style> <script type="text/javascript" src="js/jquery.min.js"></script> <script type="text/javascript"> $(function(){ $("#uploadFile").click(function(){ // 獲取要上傳的文件 var photoFile =$("#photo")[0].files[0] if(photoFile==undefined){ alert("您還未選中文件") return; } // 將文件裝入FormData對(duì)象 var formData =new FormData(); formData.append("headPhoto",photoFile) // ajax向后臺(tái)發(fā)送文件 $.ajax({ type:"post", data:formData, url:"fileUpload.do", processData:false, contentType:false, success:function(result){ // 接收后臺(tái)響應(yīng)的信息 alert(result.message) // 圖片回顯 $("#headImg").attr("src","http://192.168.8.109:8090/upload/"+result.newFileName); }, xhr: function() { var xhr = new XMLHttpRequest(); //使用XMLHttpRequest.upload監(jiān)聽上傳過程,注冊(cè)progress事件,打印回調(diào)函數(shù)中的event事件 xhr.upload.addEventListener('progress', function (e) { //loaded代表上傳了多少 //total代表總數(shù)為多少 var progressRate = (e.loaded / e.total) * 100 + '%'; //通過設(shè)置進(jìn)度條的寬度達(dá)到效果 $('.progress > div').css('width', progressRate); }) return xhr; } }) }) }) </script> </head> <body> <form action="addPlayer" method="get"> <p>賬號(hào)<input type="text" name="name"></p> <p>密碼<input type="text" name="password"></p> <p>昵稱<input type="text" name="nickname"></p> <p>頭像: <br/> <input id="photo" type="file"> <%--圖片回顯--%> <br/> <img id="headImg" style="width: 200px;height: 200px" alt="你還未上傳圖片"> <br/> <%--進(jìn)度條--%> <div class="progress"> <div></div> </div> <a id="uploadFile" href="javascript:void(0)" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >立即上傳</a> </p> <p><input type="submit" value="注冊(cè)"></p> </form> </body> </html>
八、保存完整player信息進(jìn)入數(shù)據(jù)庫
index.html
<%@ page contentType="text/html;charset=UTF-8" language="java" %> <html> <head> <title>Title</title> <style> .progress { width: 200px; height: 10px; border: 1px solid #ccc; border-radius: 10px; margin: 10px 0px; overflow: hidden; } /* 初始狀態(tài)設(shè)置進(jìn)度條寬度為0px */ .progress > div { width: 0px; height: 100%; background-color: yellowgreen; transition: all .3s ease; } </style> <script type="text/javascript" src="js/jquery.min.js"></script> <script type="text/javascript"> $(function(){ $("#uploadFile").click(function(){ // 獲取要上傳的文件 var photoFile =$("#photo")[0].files[0] if(photoFile==undefined){ alert("您還未選中文件") return; } // 將文件裝入FormData對(duì)象 var formData =new FormData(); formData.append("headPhoto",photoFile) // ajax向后臺(tái)發(fā)送文件 $.ajax({ type:"post", data:formData, url:"fileUpload.do", processData:false, contentType:false, success:function(result){ // 接收后臺(tái)響應(yīng)的信息 alert(result.message) // 圖片回顯 $("#headImg").attr("src","http://192.168.8.109:8090/upload/"+result.newFileName); // 將文件類型和文件名放入form表單 $("#photoInput").val(result.newFileName) $("#filetypeInput").val(result.filetype) }, xhr: function() { var xhr = new XMLHttpRequest(); //使用XMLHttpRequest.upload監(jiān)聽上傳過程,注冊(cè)progress事件,打印回調(diào)函數(shù)中的event事件 xhr.upload.addEventListener('progress', function (e) { //loaded代表上傳了多少 //total代表總數(shù)為多少 var progressRate = (e.loaded / e.total) * 100 + '%'; //通過設(shè)置進(jìn)度條的寬度達(dá)到效果 $('.progress > div').css('width', progressRate); }) return xhr; } }) }) }) </script> </head> <body> <form action="addPlayer" method="get"> <p>賬號(hào)<input type="text" name="name"></p> <p>密碼<input type="text" name="password"></p> <p>昵稱<input type="text" name="nickname"></p> <p>頭像: <br/> <input id="photo" type="file"> <%--圖片回顯--%> <br/> <img id="headImg" style="width: 200px;height: 200px" alt="你還未上傳圖片"> <br/> <%--進(jìn)度條--%> <div class="progress"> <div></div> </div> <a id="uploadFile" href="javascript:void(0)" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" >立即上傳</a> <%--使用隱藏的輸入框存儲(chǔ)文件名稱和文件類型--%> <input id="photoInput" type="hidden" name="photo" > <input id="filetypeInput" type="hidden" name="filetype"> </p> <p><input type="submit" value="注冊(cè)"></p> </form> </body> </html>
FileUploadController代碼
見上一步
playerController代碼
package com.lanson.controller; import com.lanson.pojo.Player; import com.lanson.service.PlayerService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RequestMapping; /** * @Author: Lansonli * @Description: MircoMessage:Mark_7001 */ @Controller public class PlayerController { @Autowired private PlayerService playerService; @RequestMapping("addPlayer") public String addPlayer(Player player){ // 調(diào)用服務(wù)層方法,將數(shù)據(jù)保存進(jìn)入數(shù)據(jù)庫 playerService.addPlayer(player); // 頁面跳轉(zhuǎn)至player信息展示頁 return "redirect:/showPlayer.jsp"; } }
Service層代碼
package com.lanson.service.impl; import com.lanson.mapper.PlayerMapper; import com.lanson.pojo.Player; import com.lanson.service.PlayerService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; /** * @Author: Lansonli * @Description: MircoMessage:Mark_7001 */ @Service public class PlayerServiceImpl implements PlayerService { @Autowired private PlayerMapper playerMapper; @Override public boolean addPlayer(Player player) { return playerMapper.addPlayer(player)>0; } }
mapper代碼
<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE mapper PUBLIC "-//mybatis.org//DTD Mapper 3.0//EN" "http://mybatis.org/dtd/mybatis-3-mapper.dtd"> <mapper namespace="com.lanson.mapper.PlayerMapper"> <insert id="addPlayer"> insert into player values(DEFAULT ,#{name},#{password},#{nickname},#{photo},#{filetype}) </insert> </mapper>
到此這篇關(guān)于SpringMVC文件上傳中要解決的問題的文章就介紹到這了,更多相關(guān)SpringMVC文件上傳問題內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
JavaCV與FFmpeg音視頻流處理技巧總結(jié)大全
JavaCV是一個(gè)開源的Java接口,它為幾個(gè)著名的計(jì)算機(jī)視覺庫(如OpenCV、FFmpeg)提供了Java封裝,這篇文章主要給大家介紹了關(guān)于JavaCV與FFmpeg音視頻流處理技巧總結(jié)的相關(guān)資料,需要的朋友可以參考下2024-05-05java實(shí)現(xiàn)計(jì)算周期性提醒的示例
本文分享一個(gè)java實(shí)現(xiàn)計(jì)算周期性提醒的示例,可以計(jì)算父親節(jié)、母親節(jié)這樣的節(jié)日,也可以定義如每月最好一個(gè)周五,以方便安排會(huì)議2014-04-04解決JavaEE開發(fā)中字符編碼出現(xiàn)亂碼的問題
下面小編就為大家?guī)硪黄鉀QJavaEE開發(fā)中字符編碼出現(xiàn)亂碼的問題。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-07-07三分鐘讀懂mybatis中resultMap和resultType區(qū)別
這篇文章主要給大家介紹了mybatis中resultMap和resultType區(qū)別的相關(guān)資料,resultType和resultMap都是mybatis進(jìn)行數(shù)據(jù)庫連接操作處理返回結(jié)果的,需要的朋友可以參考下2023-07-07SpringCloud?Nacos服務(wù)分級(jí)存儲(chǔ)模型詳解
Nacos服務(wù)分級(jí)存儲(chǔ)模型是Nacos存儲(chǔ)服務(wù)注冊(cè)信息和配置信息的核心模型之一,本文將對(duì)?Nacos?服務(wù)分級(jí)存儲(chǔ)模型進(jìn)行深入解析,感興趣的朋友一起看看吧2024-02-02Java 8 中的 10 個(gè)特性總結(jié)及詳解
本主要介紹Java 8中的新特性,這里整理了相關(guān)資料并整理了10個(gè)特性,逐一介紹說明,有興趣的朋友可以參考下2016-09-09解決SpringBoot項(xiàng)目讀取yml文件中值為中文時(shí),在視圖頁面顯示亂碼
這篇文章主要介紹了解決SpringBoot項(xiàng)目讀取yml文件中值為中文時(shí),在視圖頁面顯示亂碼的問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-08-08