我能够在开始添加此文件上载内容之前创建一本新书,所以我知道只是该模型无法将文件正确地返回到.store(file)
这是我的表格:
<form method="post" action="#" th:action="@{__${T(com.potatospy.bookcatalog.util.Mappings).ADD_BOOK}__}" enctype="multipart/form-data" th:object="${book}">
<p>Title: <input type="text" th:field="*{bookTitle}" th:text="${book.bookTitle}"/></p>
<p>Published Date: <input type="date" th:field="*{publishedDate}" th:text="${book.publishedDate}"/></p>
<p>File location: <input type="file" th:field="*{fileLoc}" name="file" ></p>
<p>Authors: <input type="text" th:field="*{authors}" th:text="${book.authors}"/></p>
<p><input type="submit" value="Submit"/></p>
</form>
这是Spring.io的代码如何上传文件。我只编辑了日志记录和异常处理:
package com.potatospy.bookcatalog.filesystem;
// This code is from https://spring.io/guides/gs/uploading-files/
// Modified and re-distributed under the ASLv2 license
// https://www.apache.org/licenses/LICENSE-2.0
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.Resource;
import org.springframework.core.io.UrlResource;
import org.springframework.stereotype.Service;
import org.springframework.util.FileSystemUtils;
import org.springframework.web.multipart.MultipartFile;
import java.io.IOException;
import java.net.MalformedURLException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;
@Slf4j
@Service
public class StorageServiceImpl implements StorageService {
private Path rootLocation;
@Autowired
private FileSystemProperties fsProperties;
@Autowired
public StorageServiceImpl(FileSystemProperties fsProperties) {
this.fsProperties = fsProperties;
log.info("fsProperties.getBookDirectory() " + fsProperties.getBookDirectory());
this.rootLocation = Paths.get(fsProperties.getBookDirectory().toString());
}
@Override
public void store(MultipartFile file) {
try {
if (file.isEmpty()) {
log.info("Failed to store empty file " + file.getOriginalFilename());
}
Files.copy(file.getInputStream(), this.rootLocation.resolve(file.getOriginalFilename()));
} catch (IOException e) {
log.info("Failed to store file " + file.getOriginalFilename(), e);
}
}
// Get relative paths to all files in rootLocation
@Override
public Stream<Path> loadAll() {
log.info("\n\n\nloadAll() ");
try {
return Files.walk(this.rootLocation, 1)
.filter(path -> !path.equals(this.rootLocation))
.map(path -> this.rootLocation.relativize(path));
} catch (IOException e) {
log.info("Failed to read stored files: {}", e);
}
return null;// Todo Original did not return anything, it called super from RuntimeException
}
@Override
public Path load(String filename) {
return rootLocation.resolve(filename);
}
@Override
public Resource loadAsResource(String filename) {
try {
Path file = load(filename);
Resource resource = new UrlResource(file.toUri());
if(resource.exists() || resource.isReadable()) {
return resource;
}
else {
log.info("Could not read file: " + filename);
}
} catch (MalformedURLException e) {
log.info("Could not read file: " + filename, e);
}
return null;// Todo Original did not return anything, it called super from RuntimeException
}
@Override
public void deleteAll() {
FileSystemUtils.deleteRecursively(rootLocation.toFile());
}
}
这是我控制器的相关行:
// Add Book View
@GetMapping(Mappings.ADD_BOOK)
public String addBook(Model model){
log.info("addBook method called");
Book newBook = new Book();
// Add the new Book (with no id) to the model
model.addAttribute(AttributeNames.BOOK, newBook);
return ViewNames.ADD_BOOK;
}
// Add Book post mapping
@PostMapping(Mappings.ADD_BOOK)
public String addBookSubmit(
@RequestParam("file") MultipartFile file,
@ModelAttribute Book newBook){
log.info("addBookSubmit called. Got postmapping to new book: {}", newBook.toString());
bookService.addBook(newBook);
storageService.store(file);
bookService.updateBook(newBook);
return "redirect:/" + Mappings.CATALOG_DETAIL;
}