最近在學習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 去聲明屬性配置類。 像上面說的同樣聲明就能夠正常運行了