詳解SpringMVC使用MultipartFile實現檔案的上傳
如果需要實現跨伺服器上傳檔案,就是將我們本地的檔案上傳到資源伺服器上,比較好的辦法就是通過ftp上傳。這裡是結合SpringMVC+ftp的形式上傳的。我們需要先懂得如何配置springMVC,然後在配置ftp,最後再結合MultipartFile上傳檔案。
springMVC上傳需要幾個關鍵jar包,spring以及關聯包可以自己配置,這裡主要說明關鍵的jar包
1:spring-web-3.2.9.RELEASE.jar (spring的關鍵jar包,版本可以自己選擇)
2:commons-io-2.2.jar (專案中用來處理IO的一些工具類包)
配置檔案
SpringMVC是用MultipartFile來進行檔案上傳的,因此我們先要配置MultipartResolver,用於處理表單中的file
1 2 3 4 5 6 7 |
<!-- 上傳檔案直譯器 -->
< bean
id = "multipartResolver"
class = "org.springframework.web.multipart.commons.CommonsMultipartResolver" >
< property
name = "defaultEncoding"
value = "utf-8"
/>
< property
name = "maxUploadSize"
value = "10485760"
/>
< property
name = "maxInMemorySize" value = "4096"
/>
< property
name = "resolveLazily"
value = "true"
/>
</ bean >
|
其中屬性詳解:
defaultEncoding配置請求的編碼格式,預設為iso-8859-1
maxUploadSize配置檔案的最大單位,單位為位元組
maxInMemorySize配置上傳檔案的快取 ,單位為位元組
resolveLazily屬性啟用是為了推遲檔案解析,以便在UploadAction 中捕獲檔案大小異常
頁面配置
在頁面的form中加上enctype="multipart/form-data"
1 |
< form
id = ""
name = ""
method = "post"
action = ""
enctype = "multipart/form-data" >
|
表單標籤中設定enctype="multipart/form-data"來確保匿名上載檔案的正確編碼。
是設定表單的MIME編碼。預設情況,這個編碼格式是application/x-www-form-urlencoded,不能用於檔案上傳;只有使用了multipart/form-data,才能完整的傳遞檔案資料,進行下面的操作。enctype="multipart/form-data"是上傳二進位制資料。form裡面的input的值以2進位制的方式傳過去,所以request就得不到值了。
編寫上傳控制類
編寫一個上傳方法,這裡沒有返回結果,需要跳轉頁面或者返回其他值可以將void改為String、Map<String,Object>等值,再return返回結果。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 |
/**
* 上傳
* @param request
* @return
*/
@ResponseBody
@RequestMapping (value =
"/upload" , method = {RequestMethod.GET, RequestMethod.POST})
public
void upload(HttpServletRequest request) {
MultipartHttpServletRequest multipartRequest=(MultipartHttpServletRequest)request;
MultipartFile file = multipartRequest.getFile( "file" ); //file是頁面input的name名
String basePath =
"檔案路徑"
try
{
MultipartResolver resolver =
new CommonsMultipartResolver(request.getSession().getServletContext());
if
(resolver.isMultipart(request)) {
String fileStoredPath =
"資料夾路徑" ;
//隨機生成檔名
String randomName = StringUtil.getRandomFileName();
String uploadFileName = file.getOriginalFilename();
if
(StringUtils.isNotBlank(uploadFileName)) {
//擷取檔案格式名
String suffix = uploadFileName.substring(uploadFileName.indexOf( "." ));
//重新拼裝檔名
String newFileName = randomName + suffix;
String savePath = basePath +
"/" + newFileName;
File saveFile =
new File(savePath);
File parentFile = saveFile.getParentFile();
if
(saveFile.exists()) {
saveFile.delete();
}
else {
if
(!parentFile.exists()) {
parentFile.mkdirs();
}
}
//複製檔案到指定路徑
FileUtils.copyInputStreamToFile(file.getInputStream(), saveFile);
//上傳檔案到伺服器
FTPClientUtil.upload(saveFile, fileStoredPath);
}
}
}
catch (Exception e) {
e.printStackTrace();
}
}
|
FTP客戶端上傳工具
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 |
package
com.yuanding.common.util;
import
java.io.File;
import
java.io.FileInputStream;
import
java.io.FileOutputStream;
import
java.io.IOException;
import
java.io.InputStream;
import
java.io.OutputStream;
import
java.net.SocketException;
import
java.util.HashMap;
import
java.util.Map;
import
java.util.Properties;
import
org.apache.commons.lang.StringUtils;
import
org.apache.commons.net.ftp.FTP;
import
org.apache.commons.net.ftp.FTPClient;
import
org.apache.commons.net.ftp.FTPReply;
import
org.slf4j.Logger;
import
org.slf4j.LoggerFactory;
/**
* FTP客戶端工具
*/
public
class FTPClientUtil {
/**
* 日誌
*/
private
static final
Logger LOGGER = LoggerFactory.getLogger(FTPClientUtil. class );
/**
* FTP server configuration--IP key,value is type of String
*/
public
static final
String SERVER_IP = "SERVER_IP" ;
/**
* FTP server configuration--Port key,value is type of Integer
*/
public
static final
String SERVER_PORT = "SERVER_PORT" ;
/**
* FTP server configuration--ANONYMOUS Log in key, value is type of Boolean
*/
public
static final
String IS_ANONYMOUS = "IS_ANONYMOUS" ;
/**
* user name of anonymous log in
*/
public
static final
String ANONYMOUS_USER_NAME = "anonymous" ;
/**
* password of anonymous log in
*/
public
static final
String ANONYMOUS_PASSWORD = "" ;
/**
* FTP server configuration--log in user name, value is type of String
*/
public
static final
String USER_NAME = "USER_NAME" ;
/**
* FTP server configuration--log in password, value is type of String
*/
public
static final
String PASSWORD = "PASSWORD" ;
/**
* FTP server configuration--PASV key, value is type of Boolean
*/
public
static final
String IS_PASV = "IS_PASV" ;
/**
* FTP server configuration--working directory key, value is type of String While logging in, the current directory
* is the user's home directory, the workingDirectory must be set based on it. Besides, the workingDirectory must
* exist, it can not be created automatically. If not exist, file will be uploaded in the user's home directory. If
* not assigned, "/" is used.
*/
public
static final
String WORKING_DIRECTORY = "WORKING_DIRECTORY" ;
public
static Map<String, Object> serverCfg =
new HashMap<String, Object>();
static
Properties prop;
static {
LOGGER.info( "開始載入ftp.properties檔案!" );
prop =
new Properties();
try
{
InputStream fps = FTPClientUtil. class .getResourceAsStream( "/ftp.properties" );
prop.load(fps);
fps.close();
}
catch (Exception e) {
LOGGER.error( "讀取ftp.properties檔案異常!" ,e);
}
serverCfg.put(FTPClientUtil.SERVER_IP, values( "SERVER_IP" ));
serverCfg.put(FTPClientUtil.SERVER_PORT, Integer.parseInt(values( "SERVER_PORT" )));
serverCfg.put(FTPClientUtil.USER_NAME, values( "USER_NAME" ));
serverCfg.put(FTPClientUtil.PASSWORD, values( "PASSWORD" ));
LOGGER.info(String.valueOf(serverCfg));
}
/**
* Upload a file to FTP server.
*
* @param serverCfg : FTP server configuration
* @param filePathToUpload : path of the file to upload
* @param fileStoredName : the name to give the remote stored file, null, "" and other blank word will be replaced
* by the file name to upload
* @throws IOException
* @throws SocketException
*/
public
static final
void upload(Map<String, Object> serverCfg, String filePathToUpload, String fileStoredName)
throws
SocketException, IOException {
upload(serverCfg,
new File(filePathToUpload), fileStoredName);
}
/**
* Upload a file to FTP server.
*
* @param serverCfg : FTP server configuration
* @param fileToUpload : file to upload
* @param fileStoredName : the name to give the remote stored file, null, "" and other blank word will be replaced
* by the file name to upload
* @throws IOException
* @throws SocketException
*/
public
static final
void upload(Map<String, Object> serverCfg, File fileToUpload, String fileStoredName)
throws
SocketException, IOException {
if
(!fileToUpload.exists()) {
throw
new IllegalArgumentException( "File to upload does not exists:"
+ fileToUpload.getAbsolutePath
());
}
if
(!fileToUpload.isFile()) {
throw
new IllegalArgumentException( "File to upload is not a file:"
+ fileToUpload.getAbsolutePath());
}
if
(StringUtils.isBlank((String) serverCfg.get(SERVER_IP))) {
throw
new IllegalArgumentException( "SERVER_IP must be contained in the FTP server configuration." );
}
transferFile( true , serverCfg, fileToUpload, fileStoredName,
null , null );
}
/**
* Download a file from FTP server
*
* @param serverCfg : FTP server configuration
* @param fileNameToDownload : file name to be downloaded
* @param fileStoredPath : stored path of the downloaded file in local
* @throws SocketException
* @throws IOException
*/
public
static final
void download(Map<String, Object> serverCfg, String fileNameToDownload, String fileStoredPath)
throws
SocketException, IOException {
if
(StringUtils.isBlank(fileNameToDownload)) {
throw
new IllegalArgumentException( "File name to be downloaded can not be blank." );
}
if
(StringUtils.isBlank(fileStoredPath)) {
throw
new IllegalArgumentException( "Stored path of the downloaded file in local can not be blank." );
}
if
(StringUtils.isBlank((String) serverCfg.get(SERVER_IP))) {
throw
new IllegalArgumentException( "SERVER_IP must be contained in the FTP server configuration." );
}
transferFile( false , serverCfg,
null , null , fileNameToDownload, fileStoredPath);
}
private
static final
void transferFile( boolean
isUpload, Map<String, Object> serverCfg, File fileToUpload,
String serverFileStoredName, String fileNameToDownload, String localFileStoredPath)
throws
SocketException,
IOException {
String host = (String) serverCfg.get(SERVER_IP);
Integer port = (Integer) serverCfg.get(SERVER_PORT);
Boolean isAnonymous = (Boolean) serverCfg.get(IS_ANONYMOUS);
String username = (String) serverCfg.get(USER_NAME);
String password = (String) serverCfg.get(PASSWORD);
Boolean isPASV = (Boolean) serverCfg.get(IS_PASV);
String workingDirectory = (String) serverCfg.get(WORKING_DIRECTORY);
FTPClient ftpClient =
new FTPClient();
InputStream fileIn =
null ;
OutputStream fileOut =
null ;
try
{
if
(port == null ) {
LOGGER.debug( "Connect to FTP server on "
+ host + ":"
+ FTP.DEFAULT_PORT);
ftpClient.connect(host);
}
else {
LOGGER.debug( "Connect to FTP server on "
+ host + ":"
+ port);
ftpClient.connect(host, port);
}
int
reply = ftpClient.getReplyCode();
if
(!FTPReply.isPositiveCompletion(reply)) {
LOGGER.error( "FTP server refuses connection" );
return ;
}
if
(isAnonymous != null
&& isAnonymous) {
username = ANONYMOUS_USER_NAME;
password = ANONYMOUS_PASSWORD;
}
LOGGER.debug( "Log in FTP server with username = "
+ username + ", password = "
+ password);
if
(!ftpClient.login(username, password)) {
LOGGER.error( "Fail to log in FTP server with username = "
+ username + ", password = "
+
password);
ftpClient.logout();
return ;
}
// Here we will use the BINARY mode as the transfer file type,
// ASCII mode is not supportted.
LOGGER.debug( "Set type of the file, which is to upload, to BINARY." );
ftpClient.setFileType(FTP.BINARY_FILE_TYPE);
if
(isPASV != null
&& isPASV) {
LOGGER.debug( "Use the PASV mode to transfer file." );
ftpClient.enterLocalPassiveMode();
}
else {
LOGGER.debug( "Use the ACTIVE mode to transfer file." );
ftpClient.enterLocalActiveMode();
}
if
(StringUtils.isBlank(workingDirectory)) {
workingDirectory =
"/" ;
}
LOGGER.debug( "Change current working directory to "
+ workingDirectory);
changeWorkingDirectory(ftpClient,workingDirectory);
if
(isUpload) { // upload
if
(StringUtils.isBlank(serverFileStoredName)) {
serverFileStoredName = fileToUpload.getName();
}
fileIn =
new FileInputStream(fileToUpload);
LOGGER.debug( "Upload file : "
+ fileToUpload.getAbsolutePath() + " to FTP server with name : "
+ serverFileStoredName);
if
(!ftpClient.storeFile(serverFileStoredName, fileIn)) {
LOGGER.error( "Fail to upload file, "
+ ftpClient.getReplyString());
}
else {
LOGGER.debug( "Success to upload file." );
}
}
else { // download
// make sure the file directory exists
File fileStored =
new File(localFileStoredPath);
if
(!fileStored.getParentFile().exists()) {
|