使用FreeMrker模板进行文件的上传和下载。
index.ftl文件。
<!DOCTYPE html> <html lang="en"> <head> <meta charset='UTF-8'> <title>${msg}</title> </head> <body> // <h1>${msg}</hl> <p>单文件上传</p> <form action="upload" method="POST" enctype="multipart/form-data"> 文件: <input type="file" name="file"/> <input type="submit"/> </form> <hr/> <p>文件下载</p> <a href="download">下载文件</a> <hr/> <p>多文件上传</p> <form action ="batch" method="POST" enctype="multipart/form-data"> <p>文件1:<input type="file" name="file"/></p> <p>文件2:<input type="file" name="file"/></p> <p><input type="submit" value="上传"/></p> </form> </body> <html>
启动类:
package com.example.demo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.stereotype.Controller; import org.springframework.ui.ModelMap; import org.springframework.web.bind.annotation.GetMapping; @SpringBootApplication @Controller public class Springboot352FreemakerApplication { public static void main(String[] args) { SpringApplication.run(Springboot352FreemakerApplication.class, args); } //运行成功 //localhost:8080 @GetMapping public String index(ModelMap modelMap){ modelMap.addAttribute("msg","文件上传下载"); return "index"; } //运行成功,功能有问题。 //2022/09/19 }
启动类目录下新建controller文件夹,创建通过文件FileController文件。
代码清单如下:
@RestController public class FileController { private static final String filepath="/Users/TMY/Downloads/"; private static final Logger log= LoggerFactory.getLogger(FileController.class); @RequestMapping(value = "/upload") public String upload(@RequestParam("file") MultipartFile file){ try{ if(file.isEmpty()){ return "文件为空"; } //获取文件名 String fileName=file.getOriginalFilename(); log.info("上传的文件名为:"+fileName); //设置文件存储路径 String path=filepath+fileName; File dest=new File(path); //检测是否存在目录 if(!dest.getParentFile().exists()){ dest.getParentFile().mkdirs();//新建文件夹 } file.transferTo(dest);//文件写入 return "上传成功"; }catch(IllegalStateException e){ e.printStackTrace(); }catch(IOException e){ e.printStackTrace(); } return "上传失败"; } @PostMapping("/batch") public String handleFileUpload(HttpServletRequest request){ List<MultipartFile> files=((MultipartHttpServletRequest) request).getFiles("file"); MultipartFile file=null; BufferedOutputStream stream=null; for(int i=0;i<files.size();++i){ file=files.get(i); if(!file.isEmpty()){ try{ byte[] bytes=file.getBytes(); stream=new BufferedOutputStream(new FileOutputStream(new File(filepath+file.getOriginalFilename())));//设置文件路径和名字。 stream.write(bytes); stream.close(); }catch(Exception e){ stream=null; return "第"+i+"个文件上传失败==》"+e.getMessage(); } }else{ return "第"+i+"个文件上传失败,因为文件为空"; } } return "上传成功"; } @GetMapping("/download") public String downloadFile(HttpServletResponse response){ String fileName="tmy.txt";//文件名 if(fileName!=null){ //设置文件路径 File file =new File(filepath+fileName); if(file.exists()){ response.setContentType("application/force-download");//设置强制下载打开 response.addHeader("Content-Disposition","attachment;fileName="+fileName);//设置文件名 byte[] buffer =new byte[1024]; FileInputStream fis=null; BufferedInputStream bis=null; try{ fis=new FileInputStream(file); bis=new BufferedInputStream(fis); OutputStream os=response.getOutputStream(); int i=bis.read(buffer); while (i!=-1){ os.write(buffer,0,1); i=bis.read(buffer); } return "下载成功"; }catch (Exception e){ e.printStackTrace(); }finally { if(bis!=null){ try{ fis.close(); }catch(IOException e){ e.printStackTrace(); } } } } } return "下载失败"; } }
运行启动类,浏览器8080端口,进入文件上传下载页面:
实测多文件上传成功且能下载,单文件上传一直失败,暂未找到问题的原因。
通过错误信息判断是file.transferTo()方法出现问题,导致上传路径出错。
查找到改进方法:
将目的文件地址 File dest = new File(filepath + File.separator + fileName);
改为 File dest = new File(new File(filepath).getAbsolutePath() + File.separator + fileName);
结果单文件上传成功运行,并且能下载文件,如下图所示。