解決MultipartFile.transferTo(dest) 報FileNotFoundExcep的問題
Spring Upload file 報錯FileNotFoundException
環(huán)境:
- Springboot 2.0.4
- JDK8
- 內(nèi)嵌 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 方法調(diào)用時,判斷如果是相對路徑,則使用temp目錄,為父目錄
因此,實際保存位置為 C:\Users\xxxx\AppData\Local\Temp\tomcat.372873030384525225.8080\work\Tomcat\localhost\ROOT\upload\doc20170816162034_001.jpg
一則,位置不對,二則沒有父目錄存在,因此產(chǎn)生上述錯誤。
解決辦法
transferTo 傳入?yún)?shù) 定義為絕對路徑
@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() 獲得字節(jié)數(shù)組,OutputStream.write(byte[] bytes)自己寫到輸出流中。
補充方法
application.properties 中增加配置項
spring.servlet.multipart.location= # Intermediate location of uploaded files.
關(guān)于上傳文件的訪問
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;//取得在服務(wù)器中的絕對路徑
System.out.println("Mapping /upload/** from " + p);
registry.addResourceHandler("/upload/**") // 外部訪問地址
.addResourceLocations("file:" + p)// springboot需要增加file協(xié)議前綴
.setCacheControl(CacheControl.maxAge(30, TimeUnit.MINUTES));// 設(shè)置瀏覽器緩存30分鐘
}
}
application.properties 中 file.upload.path=upload/
實際存儲目錄
D:/upload/2019/03081625111.jpg
訪問地址(假設(shè)應(yīng)用發(fā)布在http://www.a.com/)
http://www.a.com/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){
// 通常上傳的文件會有一個數(shù)據(jù)表來存儲,這里返回的id是記錄id
UploadFile file = conversionService.convert(id, UploadFile.class);// 這步也可以寫在請求參數(shù)中
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這個方法進行上傳文件的使用發(fā)現(xiàn)了一些路徑的一些問題,查找了一下記錄問題所在
前端上傳網(wǎng)頁,使用的是單文件上傳的方式
<!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>
后臺網(wǎng)頁
@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 方法調(diào)用時,判斷如果是相對路徑,則使用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";
}
}
}
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Maven工程搭建spring boot+spring mvc+JPA的示例
本篇文章主要介紹了Maven工程搭建spring boot+spring mvc+JPA的示例,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-01-01
Java設(shè)計模式之中介模式(Mediator模式)介紹
這篇文章主要介紹了Java設(shè)計模式之中介模式(Mediator模式)介紹,本文講解了為何使用Mediator模式、如何使用中介模式等內(nèi)容,需要的朋友可以參考下2015-03-03
SpringBoot中使用configtree讀取樹形文件目錄中的配置詳解
這篇文章主要介紹了SpringBoot中使用configtree讀取樹形文件目錄中的配置詳解,configtree通過spring.config.import?+?configtree:前綴的方式,加載以文件名為key、文件內(nèi)容為value的配置屬性,需要的朋友可以參考下2023-12-12
Java根據(jù)前端返回的字段名進行查詢數(shù)據(jù)的實現(xiàn)方法
在Java后端開發(fā)中,我們經(jīng)常需要根據(jù)前端傳遞的參數(shù)(如字段名)來動態(tài)查詢數(shù)據(jù)庫中的數(shù)據(jù),這種需求通常出現(xiàn)在需要實現(xiàn)通用查詢功能或者復(fù)雜查詢接口的場景中,所以本文介紹了Java根據(jù)前端返回的字段名進行查詢數(shù)據(jù)的實現(xiàn)方法,需要的朋友可以參考下2024-12-12

