您的位置:首页 > 教程文章 > 编程开发

解决MultipartFile.transferTo(dest) 报FileNotFoundExcep的问题

:0 :2021-10-27 21:59:48

Spring Upload file 报错FileNotFoundException
环境:
Springboot 2.0.4
JDK8
内嵌 Apache Tomcat/8.5.32
表单,enctype 和 input 的type=file 即可,例子使用单文件上传
<form enctype="multipart/form-data" method="POST"
 action="/file/fileUpload">
 图片<input type="file" name="file" />
 <input type="submit" value="上传" />
</form>
@Controller
@RequestMapping("/file")
public class UploadFileController {
 @Value("${file.upload.path}")
 private String path = "upload/";
 @RequestMapping(value = "fileUpload", method = RequestMethod.POST)
 @ResponseBody
 public String fileUpload(@RequestParam("file") MultipartFile file) {
  if (file.isEmpty()) {
   return "false";
  }
  String fileName = file.getOriginalFilename();
  File dest = new File(path + "/" + fileName);
  if (!dest.getParentFile().exists()) {
   dest.getParentFile().mkdirs();
  }
  try {
   file.transferTo(dest); // 保存文件
   return "true";
  } catch (Exception e) {
   e.printStackTrace();
   return "false";
  }
 }
}
运行在保存文件 file.transferTo(dest) 报错
问题
dest 是相对路径,指向 upload/doc20170816162034_001.jpg
file.transferTo 方法调用时,判断如果是相对路径,则使用temp目录,为父目录
因此,实际保存位置为 C:UsersxxxxAppDataLocalTemptomcat.372873030384525225.8080workTomcatlocalhostROOTuploaddoc20170816162034_001.jpg
一则,位置不对,二则没有父目录存在,因此产生上述错误。
解决办法
transferTo 传入参数 定义为绝对路径
@Controller
@RequestMapping("/file")
public class UploadFileController {
 @Value("${file.upload.path}")
 private String path = "upload/";
 @RequestMapping(value = "fileUpload", method = RequestMethod.POST)
 @ResponseBody
 public String fileUpload(@RequestParam("file") MultipartFile file) {
  if (file.isEmpty()) {
   return "false";
  }
  String fileName = file.getOriginalFilename();
  File dest = new File(new File(path).getAbsolutePath()+ "/" + fileName);
  if (!dest.getParentFile().exists()) {
   dest.getParentFile().mkdirs();
  }
  try {
   file.transferTo(dest); // 保存文件
   return "true";
  } catch (Exception e) {
   e.printStackTrace();
   return "false";
  }
 }
}
另外也可以 file.getBytes() 获得字节数组,OutputStream.write(byte[] bytes)自己写到输出流中。
补充方法
application.properties 中增加配置项
spring.servlet.multipart.location= # Intermediate location of uploaded files.
关于上传文件的访问
1、增加一个自定义的ResourceHandler把目录公布出去
// 写一个Java Config
@Configuration
public class webMvcConfig implements org.springframework.web.servlet.config.annotation.WebMvcConfigurer{
 // 定义在application.properties
 @Value("${file.upload.path}")
 private String path = "upload/";
 public void addResourceHandlers(ResourceHandlerRegistry registry) {
  String p = new File(path).getAbsolutePath() + File.separator;//取得在服务器中的绝对路径
  System.out.println("Mapping /upload/** from " + p);
  registry.addResourceHandler("/upload/**") // 外部访问地址
   .addResourceLocations("file:" + p)// springboot需要增加file协议前缀
   .setCacheControl(CacheControl.maxAge(30, TimeUnit.MINUTES));// 设置浏览器缓存30分钟
 }
}
application.properties 中 file.upload.path=upload/
实际存储目录
D:/upload/2019/03081625111.jpg
访问地址(假设应用发布在
2、在Controller中增加一个RequestMapping,把文件输出到输出流中
@RestController
@RequestMapping("/file")
public class UploadFileController {
 @Autowired
 protected HttpServletRequest request;
 @Autowired
 protected HttpServletResponse response;
 @Autowired
 protected ConversionService conversionService;
 @Value("${file.upload.path}")
 private String path = "upload/"; 
 @RequestMapping(value="/view", method = RequestMethod.GET)
 public Object view(@RequestParam("id") Integer id){
  // 通常上传的文件会有一个数据表来存储,这里返回的id是记录id
  UploadFile file = conversionService.convert(id, UploadFile.class);// 这步也可以写在请求参数中
  if(file==null){
   throw new RuntimeException("没有文件");
  }
  
  File source= new File(new File(path).getAbsolutePath()+ "/" + file.getPath());
  response.setContentType(contentType);
  try {
   FileCopyUtils.copy(new FileInputStream(source), response.getOutputStream());
  } catch (Exception e) {
   e.printStackTrace();
  }
  return null;
 }
}
MultipartFile.transferTo(dest) 报找不到文件
今天使用transferTo这个方法进行上传文件的使用发现了一些路径的一些问题,查找了一下记录问题所在
前端上传网页,使用的是单文件上传的方式
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
</head>
<body>
    <form enctype="multipart/form-data" method="post" action="/upload">
        文件:<input type="file" name="head_img">
        姓名:<input type="text" name="name">
        <input type="submit" value="上传">
    </form>
</body>
</html>
后台网页
@Controller
@RequestMapping("/file")
public class UploadFileController {
    @Value("${file.upload.path}")
    private String path = "upload/";
    @RequestMapping(value = "fileUpload", method = RequestMethod.POST)
    @ResponseBody
    public String fileUpload(@RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {
            return "false";
        }
        String fileName = file.getOriginalFilename();
        File dest = new File(path + "/" + fileName);
        if (!dest.getParentFile().exists()) {
            dest.getParentFile().mkdirs();
        }
        try {
            file.transferTo(dest); // 保存文件
            return "true";
        } catch (Exception e) {
            e.printStackTrace();
            return "false";
        }
    }
}
这个确实存在一些问题
路径是不对的
dest 是相对路径,指向 upload/doc20170816162034_001.jpg
file.transferTo 方法调用时,判断如果是相对路径,则使用temp目录,为父目录
因此,实际保存位置为 C:UsersxxxxAppDataLocalTemptomcat.372873030384525225.8080workTomcatlocalhostROOTuploaddoc20170816162034_001.jpg
所以改为:
@Controller
@RequestMapping("/file")
public class UploadFileController {
    @Value("${file.upload.path}")
    private String path = "upload/";
    @RequestMapping(value = "fileUpload", method = RequestMethod.POST)
    @ResponseBody
    public String fileUpload(@RequestParam("file") MultipartFile file) {
        if (file.isEmpty()) {
            return "false";
        }
        String fileName = file.getOriginalFilename();
        File dest = new File(new File(path).getAbsolutePath()+ "/" + fileName);
        if (!dest.getParentFile().exists()) {
            dest.getParentFile().mkdirs();
        }
        try {
            file.transferTo(dest); // 保存文件
            return "true";
        } catch (Exception e) {
            e.printStackTrace();
            return "false";
        }
    }
}
以上为个人经验,希望能给大家一个参考,也希望大家多多支持无名。

java实现对Hadoop的操作
Java中多线程下载图片并压缩能提高效率吗

同类资源