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

时间:2021-08-21 08:13:59

如果需要实现跨服务器上传文件,就是将我们本地的文件上传到资源服务器上,比较好的办法就是通过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()) {
          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

?
1
2
3
4
5
6
7
8
9
10
11
#服务器地址
SERVER_IP=192.168.1.1
 
#服务器端口
SERVER_PORT=21
 
#帐号名
USER_NAME=userftp
 
#密码
#PASSWORD=passwordftp

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:http://blog.csdn.net/w410589502/article/details/53906145

相关文章