关于MultipartFile中transferTo方法使用记录

最近在项目中使用springboot写了一个文件上传的功能,但是遇到了路径上传错误的问题,以下是正确代码示范:
复制代码
 1 @RequestMapping(value = "/sc/uploadAcceptanceData", method = RequestMethod.POST)
 2     @ResponseBody
 3     public Map<String, Object> uploadAcceptanceData(String metaData,MultipartFile[] uploadFile) {
 4         Map<String, Object> args = JSONUtils.stringToMap(metaData);
 5         Map<String, Object> mp = new HashMap<String, Object>();
 6         try {
 7             String name = args.get("NAME").toString();
 8             // 获取路径
 9             String storePath = CacheManagerOper.getEcmStores().get("store04").getStorePath();
10             String templatePath = storePath + File.separator + name + File.separator;
11             if (uploadFile != null && uploadFile.length > 0) {
12                 for (MultipartFile multipartFile : uploadFile) {
13                     // 获取文件原本的名字
14                     String originName = multipartFile.getOriginalFilename();
15                     // 保存文件的文件夹
16                     File saveFile = new File(templatePath+originName);
17                     // 判断路径是否存在,不存在则自动创建
18                     if (!saveFile.getParentFile().exists()) {
19                         saveFile.getParentFile().mkdirs();
20                     }
21                     //将文件保存在目标路径
22                     multipartFile.transferTo(saveFile.getAbsoluteFile());
23                 }
24                 mp.put("code", ActionContext.SUCESS);
25             }
26         } catch (Exception ex) {
27             mp.put("code", ActionContext.FAILURE);
28             mp.put("message", ex.getMessage());
29         }
30         return mp;
31     }
复制代码

以下是错误代码示范

复制代码
 1 @RequestMapping(value = "/sc/uploadAcceptanceData", method = RequestMethod.POST)
 2     @ResponseBody
 3     public Map<String, Object> uploadAcceptanceData(String metaData,MultipartFile[] uploadFile) {
 4         Map<String, Object> args = JSONUtils.stringToMap(metaData);
 5         Map<String, Object> mp = new HashMap<String, Object>();
 6         try {
 7             String name = args.get("NAME").toString();
 8             // 获取路径
 9             String storePath = CacheManagerOper.getEcmStores().get("store04").getStorePath();
10             String templatePath = storePath + File.separator + name + File.separator;
11             if (uploadFile != null && uploadFile.length > 0) {
12                 for (MultipartFile multipartFile : uploadFile) {
13                     // 获取文件原本的名字
14                     String originName = multipartFile.getOriginalFilename();
15                     // 保存文件的文件夹
16                     File saveFile = new File(templatePath+originName);
17                     // 判断路径是否存在,不存在则自动创建
18                     if (!saveFile.getParentFile().exists()) {
19                         saveFile.getParentFile().mkdirs();
20                     }
21                     //将文件保存在目标路径
22                     multipartFile.transferTo(saveFile);
23                 }
24                 mp.put("code", ActionContext.SUCESS);
25             }
26         } catch (Exception ex) {
27             mp.put("code", ActionContext.FAILURE);
28             mp.put("message", ex.getMessage());
29         }
30         return mp;
31     }
复制代码

问题就出在了如下代码,我在日志中打印了路径的位置,显示是没有问题,当时一旦执行到下行代码就会产生一个FileNotFoundException,但是我前面的代码是执行了,并且创建了一个文件夹的。

 multipartFile.transferTo(saveFile);

修改此处传如的参数,改为文件的绝对路径,上传成功!

 multipartFile.transferTo(saveFile.getAbsoluteFile());

上面失败与成功只是因为路径所代表的是相对路径和绝对路径的区别。这就说明是MultiparFile的transferTo方法有问题了。下面看一下源码:

复制代码
 1 @Override
 2 public void transferTo(File dest) throws IOException, IllegalStateException {
 3     this.part.write(dest.getPath());
 4     if (dest.isAbsolute() && !dest.exists()) {
 5         // Servlet 3.0 Part.write is not guaranteed to support absolute file paths:
 6         // may translate the given path to a relative location within a temp dir
 7         // (e.g. on Jetty whereas Tomcat and Undertow detect absolute paths).
 8         // At least we offloaded the file from memory storage; it'll get deleted
 9         // from the temp dir eventually in any case. And for our user's purposes,
10         // we can manually copy it to the requested location as a fallback.
11         FileCopyUtils.copy(this.part.getInputStream(), Files.newOutputStream(dest.toPath()));
12     }
13 }
14 @Override
15 public void write(String fileName) throws IOException {
16     File file = new File(fileName);
17     if (!file.isAbsolute()) {
18         file = new File(location, fileName);
19     }
20     try {
21         fileItem.write(file);
22     } catch (Exception e) {
23         throw new IOException(e);
24     }
25 }
复制代码

通过源码分析我们可以知道,这是因为transferTo的参数,如果是相对路径的话,程序会自己拼接一个父路径,因为我指定的相对路径中带有一个不存在的路径,如果尝试保存是会失败的。但是如果你传入的参数只是一个文件名,那应该就能保存成功。

 

posted @   zh_niu  阅读(1968)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
点击右上角即可分享
微信分享提示