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

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)@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";}}}

运行在保存文件 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

一则,位置不对,二则没有父目录存在,因此产生上述错误。

解决办法

transferTo 传入参数 定义为绝对路径

@Controller@RequestMapping("/file")public class UploadFileController {@Value("${file.upload.path}")private String path = "upload/";@RequestMapping(value = "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";}}}

另外也可以 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://img.68idc.cn/uploadfile/allimg/java/03081625111.jpg

2、在Controller中增加一个RequestMapping,把文件输出到输出流中

@RestController@RequestMapping("/file")public class UploadFileController {@Autowiredprotected HttpServletRequest request;@Autowiredprotected HttpServletResponse response;@Autowiredprotected ConversionService conversionService;@Value("${file.upload.path}")private String path = "upload/";@RequestMapping(value="/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这个方法进行上传文件的使用发现了一些路径的一些问题,查找了一下记录问题所在

前端上传网页,使用的是单文件上传的方式

<!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:\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 = "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";        }    }}

以上为个人经验,希望能给大家一个参考,也希望大家多多支持。

或者在河边放下一盏写着心愿的河灯,祝愿一切安好。

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

相关文章:

你感兴趣的文章:

标签云: