SpringMVC文件上傳中要解決的問題大匯總
SpringMVC文件上傳中要解決的問題
一、中文文件名編碼問題
通過過濾器解決
二、文件位置存儲問題
放在當(dā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 {
// 指定文件存儲目錄為我們項目部署環(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();
// 文件存儲位置
File file =new File(dir,originalFilename);
// 文件保存
headPhoto.transferTo(file);
return "OK";
}
}
在SpringMVC中配置靜態(tài)資源放行
<mvc:resources mapping="/upload/**" location="/upload/"></mvc:resources>
三、文件名沖突問題
使用UUID對文件名進行重命名。

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 {
// 指定文件存儲目錄為我們項目部署環(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);
// 文件存儲位置
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;
}
// 指定文件存儲目錄為我們項目部署環(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);
// 文件存儲位置
File file =new File(dir,newFileName);
// 文件保存
headPhoto.transferTo(file);
// 上傳成功之后,把文件的名字和文件的類型返回給瀏覽器
map.put("message", "上傳成功");
map.put("newFileName", newFileName);
map.put("filetype", headPhoto.getContentType());
return map;
}
}
通過文件上傳解析組件控制。
但是會出現(xiàn)異常,后期可以可以配置一個異常解析器解決。
<!--文件上傳解析組件
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對象
var formData =new FormData();
formData.append("headPhoto",photoFile)
// ajax向后臺發(fā)送文件
$.ajax({
type:"post",
data:formData,
url:"fileUpload.do",
processData:false,
contentType:false,
success:function(result){
// 接收后臺響應(yīng)的信息
alert(result.message)
// 圖片回顯
$("#headImg").attr("src","upload/"+result.newFileName);
}
})
})
})
</script>
</head>
<body>
<form action="addPlayer" method="get">
<p>賬號<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="注冊"></p>
</form>
</body>
</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è)置進度條寬度為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對象
var formData =new FormData();
formData.append("headPhoto",photoFile)
// ajax向后臺發(fā)送文件
$.ajax({
type:"post",
data:formData,
url:"fileUpload.do",
processData:false,
contentType:false,
success:function(result){
// 接收后臺響應(yīng)的信息
alert(result.message)
// 圖片回顯
$("#headImg").attr("src","upload/"+result.newFileName);
},
xhr: function() {
var xhr = new XMLHttpRequest();
//使用XMLHttpRequest.upload監(jiān)聽上傳過程,注冊progress事件,打印回調(diào)函數(shù)中的event事件
xhr.upload.addEventListener('progress', function (e) {
//loaded代表上傳了多少
//total代表總數(shù)為多少
var progressRate = (e.loaded / e.total) * 100 + '%';
//通過設(shè)置進度條的寬度達到效果
$('.progress > div').css('width', progressRate);
})
return xhr;
}
})
})
})
</script>
</head>
<body>
<form action="addPlayer" method="get">
<p>賬號<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/>
<%--進度條--%>
<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="注冊"></p>
</form>
</body>
</html>七、單獨準(zhǔn)備文件存儲服務(wù)器
分服務(wù)器上傳作用
- 數(shù)據(jù)庫服務(wù)器:運行我們的數(shù)據(jù)庫
- 緩存和消息服務(wù)器:負責(zé)處理大并發(fā)訪問的緩存和消息
- 文件服務(wù)器:負責(zé)存儲用戶上傳文件的服務(wù)器。
- 應(yīng)用服務(wù)器:負責(zé)部署我們的應(yīng)用
在實際開發(fā)中,我們會有很多處理不同功能的服務(wù)器。(注意:此處說的不是服務(wù)器集群)
總結(jié):分服務(wù)器處理的目的是讓服務(wù)器各司其職,從而提高我們項目的運行效率。
分服務(wù)器工作示意圖

單獨解壓一個Tomcat作為文件服務(wù)器

設(shè)置遠程服務(wù)器端口號


遠程服務(wù)器中設(shè)置非只讀

webapps下創(chuàng)建一個upload目錄

啟動測試

項目中導(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 {
// 文件存儲位置
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對象
Client client=Client.create();
WebResource resource = client.resource(FILESERVER + newFileName);
// 文件保存到另一個服務(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è)置進度條寬度為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對象
var formData =new FormData();
formData.append("headPhoto",photoFile)
// ajax向后臺發(fā)送文件
$.ajax({
type:"post",
data:formData,
url:"fileUpload.do",
processData:false,
contentType:false,
success:function(result){
// 接收后臺響應(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)聽上傳過程,注冊progress事件,打印回調(diào)函數(shù)中的event事件
xhr.upload.addEventListener('progress', function (e) {
//loaded代表上傳了多少
//total代表總數(shù)為多少
var progressRate = (e.loaded / e.total) * 100 + '%';
//通過設(shè)置進度條的寬度達到效果
$('.progress > div').css('width', progressRate);
})
return xhr;
}
})
})
})
</script>
</head>
<body>
<form action="addPlayer" method="get">
<p>賬號<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/>
<%--進度條--%>
<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="注冊"></p>
</form>
</body>
</html>
八、保存完整player信息進入數(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è)置進度條寬度為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對象
var formData =new FormData();
formData.append("headPhoto",photoFile)
// ajax向后臺發(fā)送文件
$.ajax({
type:"post",
data:formData,
url:"fileUpload.do",
processData:false,
contentType:false,
success:function(result){
// 接收后臺響應(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)聽上傳過程,注冊progress事件,打印回調(diào)函數(shù)中的event事件
xhr.upload.addEventListener('progress', function (e) {
//loaded代表上傳了多少
//total代表總數(shù)為多少
var progressRate = (e.loaded / e.total) * 100 + '%';
//通過設(shè)置進度條的寬度達到效果
$('.progress > div').css('width', progressRate);
})
return xhr;
}
})
})
})
</script>
</head>
<body>
<form action="addPlayer" method="get">
<p>賬號<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/>
<%--進度條--%>
<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>
<%--使用隱藏的輸入框存儲文件名稱和文件類型--%>
<input id="photoInput" type="hidden" name="photo" >
<input id="filetypeInput" type="hidden" name="filetype">
</p>
<p><input type="submit" value="注冊"></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ù)保存進入數(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)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java ArrayList與Vector和LinkedList的使用及源碼分析
ArrayList、Vector、LinkedList類均在java.util包中,均為可伸縮數(shù)組,即可以動態(tài)改變長度的數(shù)組。ArrayList 和 Vector都是基于存儲元素的Object[] array來實現(xiàn)的,它們會在內(nèi)存中開辟一塊連續(xù)的內(nèi)存來存儲2022-11-11
SpringBoot實現(xiàn)多環(huán)境配置文件切換教程詳解
很多時候,我們項目在開發(fā)環(huán)境和生成環(huán)境的環(huán)境配置是不一樣的,例如,數(shù)據(jù)庫配置,這個時候就需要切換環(huán)境配置文件。本文將詳細講解SpringBoot如何切換配置文件,需要的可以參考一下2022-03-03
實踐講解SpringBoot自定義初始化Bean+HashMap優(yōu)化策略模式
本篇講解了SpringBoot自定義初始化Bean+HashMap優(yōu)化策略模式,通過實踐的方式更通俗易懂,對此不了解的同學(xué)跟著小編往下看吧2021-09-09
hadoop運行java程序(jar包)并運行時動態(tài)指定參數(shù)
這篇文章主要介紹了hadoop如何運行java程序(jar包)并運行時動態(tài)指定參數(shù),使用hadoop 運行 java jar包,Main函數(shù)一定要加上全限定類名,需要的朋友可以參考下2021-06-06
java實現(xiàn)阿拉伯?dāng)?shù)字轉(zhuǎn)漢字?jǐn)?shù)字
這篇文章主要為大家詳細介紹了java實現(xiàn)阿拉伯?dāng)?shù)字轉(zhuǎn)換為漢字?jǐn)?shù)字源代碼,具有一定的參考價值,感興趣的小伙伴們可以參考一下2019-04-04

