解决MultipartFile.transferTo(dest)|解决MultipartFile.transferTo(dest) 报FileNotFoundExcep的问题
Spring Upload file 报错FileNotFoundException
环境:
- Springboot 2.0.4
- JDK8
- 内嵌 Apache Tomcat/8.5.32
@Controller@RequestMapping("/file")public class UploadFileController { @Value("${file.upload.path}") private String path = "upload/"; @RequestMapping(value = "https://www.it610.com/article/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:\Users\xxxx\AppData\Local\Temp\tomcat.372873030384525225.8080\work\Tomcat\localhost\ROOT\upload\doc20170816162034_001.jpg一则,位置不对,二则没有父目录存在,因此产生上述错误。
解决办法
【解决MultipartFile.transferTo(dest)|解决MultipartFile.transferTo(dest) 报FileNotFoundExcep的问题】transferTo 传入参数 定义为绝对路径
@Controller@RequestMapping("/file")public class UploadFileController { @Value("${file.upload.path}") private String path = "upload/"; @RequestMapping(value = "https://www.it610.com/article/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 @Configurationpublic 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访问地址(假设应用发布在http://www.a.com/)
http://www.a.com/upload/2019/03081625111.jpg2、在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="https://www.it610.com/view", method = RequestMethod.GET) public Object view(@RequestParam("id") Integer id){// 通常上传的文件会有一个数据表来存储,这里返回的id是记录idUploadFile 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这个方法进行上传文件的使用发现了一些路径的一些问题,查找了一下记录问题所在
前端上传网页,使用的是单文件上传的方式
Title - 锐客网
后台网页
@Controller@RequestMapping("/file")public class UploadFileController {@Value("${file.upload.path}")private String path = "upload/"; @RequestMapping(value = "https://www.it610.com/article/fileUpload", method = RequestMethod.POST)@ResponseBodypublic 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:\Users\xxxx\AppData\Local\Temp\tomcat.372873030384525225.8080\work\Tomcat\localhost\ROOT\upload\doc20170816162034_001.jpg所以改为:
@Controller@RequestMapping("/file")public class UploadFileController {@Value("${file.upload.path}")private String path = "upload/"; @RequestMapping(value = "https://www.it610.com/article/fileUpload", method = RequestMethod.POST)@ResponseBodypublic 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"; }}}
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
推荐阅读
- parallels|parallels desktop 解决网络初始化失败问题
- 考研英语阅读终极解决方案——阅读理解如何巧拿高分
- MediaRecorder前后摄像头同时录像
- MybatisPlus|MybatisPlus LambdaQueryWrapper使用int默认值的坑及解决
- SpringBoot调用公共模块的自定义注解失效的解决
- Node.js中readline模块实现终端输入
- 解决SpringBoot引用别的模块无法注入的问题
- 【Leetcode/Python】001-Two|【Leetcode/Python】001-Two Sum
- leetcode|leetcode 92. 反转链表 II
- LintCode|LintCode 545 [Top k Largest Number II]