詳解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
<!-- 上傳文件解釋器 --> <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配置文件的最大單位,單位為字節(jié)
maxInMemorySize配置上傳文件的緩存 ,單位為字節(jié)
resolveLazily屬性啟用是為了推遲文件解析,以便在UploadAction 中捕獲文件大小異常
頁面配置
在頁面的form中加上enctype="multipart/form-data"
<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返回結果。
/** * 上傳 * @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客戶端上傳工具
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()) { fileStored.getParentFile().mkdirs(); } fileOut = new FileOutputStream(fileStored); LOGGER.debug("Download file : " + fileNameToDownload + " from FTP server to local : " + localFileStoredPath); if (!ftpClient.retrieveFile(fileNameToDownload, fileOut)) { LOGGER.error("Fail to download file, " + ftpClient.getReplyString()); } else { LOGGER.debug("Success to download file."); } } ftpClient.noop(); ftpClient.logout(); } finally { if (ftpClient.isConnected()) { try { ftpClient.disconnect(); } catch (IOException f) { } } if (fileIn != null) { try { fileIn.close(); } catch (IOException e) { } } if (fileOut != null) { try { fileOut.close(); } catch (IOException e) { } } } } private static final boolean changeWorkingDirectory(FTPClient ftpClient, String workingDirectory) throws IOException{ if(!ftpClient.changeWorkingDirectory(workingDirectory)){ String [] paths = workingDirectory.split("/"); for(int i=0 ;i<paths.length ;i++){ if(!"".equals(paths[i])){ if(!ftpClient.changeWorkingDirectory(paths[i])){ ftpClient.makeDirectory(paths[i]); ftpClient.changeWorkingDirectory(paths[i]); } } } } return true; } public static final void upload(Map<String, Object> serverCfg, String filePathToUpload, String fileStoredPath, String fileStoredName) throws SocketException, IOException { upload(serverCfg, new File(filePathToUpload), fileStoredPath, fileStoredName); } public static final void upload(Map<String, Object> serverCfg, File fileToUpload, String fileStoredPath, String fileStoredName) throws SocketException, IOException { if(fileStoredPath!=null && !"".equals(fileStoredPath)){ serverCfg.put(WORKING_DIRECTORY, fileStoredPath); } upload(serverCfg, fileToUpload, fileStoredName); } public static final void upload(String filePathToUpload, String fileStoredPath)throws SocketException, IOException { upload(serverCfg, filePathToUpload, fileStoredPath, ""); } public static final void upload(File fileToUpload, String fileStoredPath)throws SocketException, IOException { upload(serverCfg, fileToUpload, fileStoredPath, ""); } public static String values(String key) { String value = prop.getProperty(key); if (value != null) { return value; } else { return null; } } }
ftp.properties
#服務器地址 SERVER_IP=192.168.1.1 #服務器端口 SERVER_PORT=21 #帳號名 USER_NAME=userftp #密碼 #PASSWORD=passwordftp
以上就是本文的全部內容,希望對大家的學習有所幫助,也希望大家多多支持腳本之家。
相關文章
在IntelliJ IDEA中創(chuàng)建和運行java/scala/spark程序的方法
這篇文章主要介紹了在IntelliJ IDEA中創(chuàng)建和運行java/scala/spark程序的教程,本文通過實例代碼給大家介紹的非常詳細,對大家的學習或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-05-05Mybatis-Plus使用@TableField實現自動填充日期的代碼示例
數據庫中經常有create_time,update_time兩個字段,在代碼中設置時間有點太麻煩了?mybatis-plus可以幫我們自動填充,本文主要介紹了Mybatis-Plus使用@TableField實現自動填充日期的代碼示例,感興趣的可以了解一下2022-04-04詳解SpringBoot如何創(chuàng)建自定義Starter
Spring Boot的自動配置機制為開發(fā)人員提供了一種輕松集成和配置各種功能的便捷方式,本文將深入探討在Spring Boot中如何創(chuàng)建自定義Starter,為構建模塊化且易維護的應用提供有力的支持,需要的朋友可以參考下2024-02-02Spring Boot集成Swagger接口分類與各元素排序問題
這篇文章主要介紹了Spring Boot集成Swagger接口分類與各元素排序問題,首先我們需要對Swagger中的接口也就是以Controller 層作為第一級梯度進行組織的,Controller在我們實際開發(fā)中,與其他具體接口之間是存在一對多的關系,本文給大家介紹的非常詳細,需要的朋友參考下吧2023-10-10java教程散列表和樹所對應容器類及HashMap解決沖突學習
本篇篇文章是java教程,主要介紹了java教程散列表,樹所對應容器類及HashMap解決沖突的學習,有需要的朋友可以借鑒參考下,希望能夠有所幫助2021-10-10