最近在学习Spring Boot,跟着官方demo学习仍是会遇到很多坑,写个文章记录下,以便往后查阅。html
使用@Controller注解声明接受请求,调用@Autowired自动注入的servcie来保存上传的文件,同时提供文件下载功能。spring
使用thymeleaf模板来处理html页面请求。
用@ConfigurationProperties注解来声明属性,配置文件存放目录。app
在控制器中@Controller注解来代表这是一个控制层bean,能够接受http请求;
使用@Autowired注解来自动注入service类,用来执行对文件的操做;
分别使用@GetMapping和@PostMapping来接受GET、POST方法;
经过 return "uploadForm"; 的样子,交给模板引擎thymeleaf去处理,返回template目录下的uploadForm.html文件,并“注入”响应的属性 如files、message等。ide
@Controller // 控制器注解 public class FileUploadController { private final StorageService storageService; // 下面自动注入 @Autowired public FileUploadController(StorageService storageService) { this.storageService = storageService; } @GetMapping("/") public String listUploadedFiles(Model model) throws IOException { model.addAttribute("files", storageService.loadAll().map( path -> MvcUriComponentsBuilder.fromMethodName(FileUploadController.class, "serveFile", path.getFileName().toString()).build().toString()) .collect(Collectors.toList())); return "uploadForm"; // 由模板引擎负责返回 uploadForm.html,在template目录下。 } @GetMapping("/files/{filename:.+}") // 下载文件 @ResponseBody public ResponseEntity<Resource> serveFile(@PathVariable String filename) { Resource file = storageService.loadAsResource(filename); return ResponseEntity.ok().header(HttpHeaders.CONTENT_DISPOSITION, "attachment; filename=\"" + file.getFilename() + "\"").body(file); } @PostMapping("/") public String handleFileUpload(@RequestParam("file") MultipartFile file, RedirectAttributes redirectAttributes) { storageService.store(file); redirectAttributes.addFlashAttribute("message", "You successfully uploaded " + file.getOriginalFilename() + "!"); return "redirect:/"; // 跳转到 get的请求里(上面的listUploadedFiles方法) } }
这个类主要用来执行一些文件处理操做,没什么特殊的,spring-boot
比较坑的是,由于用到配置属性,仅仅用Autowired来注入仍是不行的, 还必须使用 @EnableConfigurationProperties(StorageProperties.class) 来声明配置属性类,这个比较坑。。学习
@Service //声明service @EnableConfigurationProperties(StorageProperties.class) // 容许使用配置注解 public class FileSystemStorageService implements StorageService { private final Path rootLocation; @Autowired // 自动注入 public FileSystemStorageService(StorageProperties properties) { this.rootLocation = Paths.get(properties.getLocation()); }
使用@ConfigurationProperties声明这是一个属性配置类,参数声明顶级命名空间。ui
比较坑的是, 须要在pom.xml里引入如下依赖:this
<dependency> <groupId> org.springframework.boot </groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional> true </optional> </dependency>
而后就能够正常使用了。。。code
@ConfigurationProperties("storage") public class StorageProperties { /** * Folder location for storing files */ private String location = "upload-dir"; public String getLocation() { return location; } public void setLocation(String location) { this.location = location; } }
以上配置完成后,能够在application.properties 文件里添加 storage.location = myFiles
来指明文件存储路径。。。orm
在学习的过程当中可能会出现 “Re-run spring boot configuration annotation”的错误,这个就是由于在service中只用Autowired去自动注入了,而没有使用 EnableConfigurationProperties 去声明属性配置类。 像上面说的同样声明就能够正常运行了