详解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配置文件的最大单位,单位为字节
maxInMemorySize配置上传文件的缓存 ,单位为字节
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
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。