详解SpringMVC使用MultipartFile实现文件的上传

简介: 详解SpringMVC使用MultipartFile实现文件的上传

本篇文章主要介绍了SpringMVC使用MultipartFile实现文件的上传,本地的文件上传到资源服务器上,比较好的办法就是通过ftp上传。这里是结合SpringMVC+ftp的形式上传的,有兴趣的可以了解一下。

如果需要实现跨服务器上传文件,就是将我们本地的文件上传到资源服务器上,比较好的办法就是通过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
相关文章
|
11月前
|
Web App开发 XML Java
SpringMVC使用MultipartResolver和MultipartFile实现文件上传
SpringMVC使用MultipartResolver和MultipartFile实现文件上传
799 0
|
1天前
|
缓存 前端开发
后端MultipartFile接收文件转Base64
后端MultipartFile接收文件转Base64
14 5
|
6月前
|
XML 前端开发 Java
怎样将MultipartFile和File互转
该文介绍了如何在Java开发中优雅地转换MultipartFile和File。MultipartFile是Spring框架用于接收上传文件的类,而File是操作系统文件的代表。文章提供了三种将MultipartFile转换为File的方法:使用`transferTo`方法、FileOutputStream和Java NIO。另外,还介绍了在测试场景下将File转换为MultipartFile,通过MockMultipartFile实现。
578 1
|
6月前
|
XML Java Maven
如何将MultipartFile转换为File
该文介绍了MultipartFile(Spring框架)与File(Java标准库)的区别,主要讨论了如何将MultipartFile转换为File的三种方法:使用`transferTo`、`FileOutputStream`和Java NIO,并提到了File转MultipartFile常用于测试,可通过MockMultipartFile实现。
248 0
|
存储 前端开发 Java
MultipartFile实现文件上传和下载(Springboot)
MultipartFile实现文件上传和下载(Springboot)
600 0
|
6月前
|
Java
【Java报错】MultipartFile 类型文件上传 Current request is not a multipart request 问题处理(postman添加MultipartFile)
【Java报错】MultipartFile 类型文件上传 Current request is not a multipart request 问题处理(postman添加MultipartFile)
617 0
|
11月前
下载文件url为MultipartFile
下载文件url为MultipartFile
178 0
MultipartFile多文件上传/通过文件夹解析所有文件
MultipartFile多文件上传/通过文件夹解析所有文件
228 0