Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/spring-mvc/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring 在HttpSession中存储多部分文件_Spring_Spring Mvc_Spring Boot_Thymeleaf - Fatal编程技术网

Spring 在HttpSession中存储多部分文件

Spring 在HttpSession中存储多部分文件,spring,spring-mvc,spring-boot,thymeleaf,Spring,Spring Mvc,Spring Boot,Thymeleaf,我正在尝试创建一个Spring引导应用程序,该应用程序上载文件并将其存储在HttpSession中,以备将来使用(仅用于教育目的)。我对文件“MultipartFile getSize()有问题。它在POST处理程序方法中返回非零值,每次我从get处理程序方法中的HttpSession获取这些值时,它都返回零。同时getOriginalFileName()返回正确的名称。所以我的“已加载文件:”表正确显示文件名,但大小为零 也许我试图在HttpSession中存储MultipartFile在概念

我正在尝试创建一个Spring引导应用程序,该应用程序上载文件并将其存储在HttpSession中,以备将来使用(仅用于教育目的)。我对文件“MultipartFile getSize()有问题。它在POST处理程序方法中返回非零值,每次我从get处理程序方法中的HttpSession获取这些值时,它都返回零。同时getOriginalFileName()返回正确的名称。所以我的“已加载文件:”表正确显示文件名,但大小为零

也许我试图在HttpSession中存储MultipartFile在概念上是错误的

作为模板,我使用的是Thymeleaf

以下是一个模板:

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:th="http://www.thymeleaf.org"
      lang="en">
<head>
    <title>File Uploader</title>
</head>
<body>
<form method="POST" action="upload" enctype="multipart/form-data">
    <input type="file" name="files" id="files" multiple="multiple"/> <br/>
    <input type="submit" value="Upload" name="upload" id="upload"/>
    <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
</form>
<h3>Loaded files:</h3>
<table border="1px">
    <thead>
    <tr>
        <td>File name</td>
        <td>Size</td>
    </tr>
    </thead>
    <tr th:each="file : ${uploadedFiles}">
        <td th:text="${file.originalFilename}"/>
        <td th:text="${file.size}"/>
    </tr>
</table>
<form method="POST" action="confirm">
    <input type="submit" value="Confirm" name="confirm" id="confirm"/>
    <input type="hidden" th:name="${_csrf.parameterName}" th:value="${_csrf.token}"/>
</form>
</body>
</html>

文件上传

加载的文件: 文件名 大小
这是一个控制器:

@Controller
public class IndexController {
    @RequestMapping("/")
    public String index(Model model, HttpSession httpSession) {
        List<MultipartFile> uploadedFiles = (List<MultipartFile>) httpSession.getAttribute("uploadedFiles");
        model.addAttribute("uploadedFiles", uploadedFiles);
        return "index";
    }

    @RequestMapping(value = "upload", method = RequestMethod.POST)
    public String index(@RequestParam("files") MultipartFile[] files, HttpSession httpSession) {
        List<MultipartFile> uploadedFiles = (List<MultipartFile>) httpSession.getAttribute("uploadedFiles");
        if (uploadedFiles != null) {
            uploadedFiles.addAll(Arrays.asList(files));
        } else {
            uploadedFiles = Arrays.asList(files);
        }
        httpSession.setAttribute("uploadedFiles", uploadedFiles);
        return "redirect:";
    }
}
@Controller
@SessionAttributes(value = {"uploadedFiles"})
public class IndexController {
    @ModelAttribute("uploadedFiles")
    public List<UploadedFile> initUploadedFiles() {
        return new ArrayList<>();
    }

    @RequestMapping("/")
    public String index() {
        return "index";
    }

    @RequestMapping(value = "upload", method = RequestMethod.POST)
    public String index(Model model, @RequestParam MultipartFile[] files, @ModelAttribute("uploadedFiles") List<UploadedFile> uploadedFiles) {
        for (MultipartFile file : files) {
            try {
                uploadedFiles.add(new UploadedFile(file.getOriginalFilename(), file.getBytes()));
            } catch (IOException e) {
                throw new RuntimeException("Can't read file " + file.getOriginalFilename(), e);
            }
        }
        model.addAttribute("uploadedFiles", uploadedFiles);
        return "redirect:";
    }
}
@控制器
公共类索引控制器{
@请求映射(“/”)
公共字符串索引(模型模型,HttpSession HttpSession){
List uploadedFiles=(List)httpSession.getAttribute(“uploadedFiles”);
model.addAttribute(“uploadedFiles”,uploadedFiles);
返回“索引”;
}
@RequestMapping(value=“upload”,method=RequestMethod.POST)
公共字符串索引(@RequestParam(“files”)MultipartFile[]files,HttpSession HttpSession){
List uploadedFiles=(List)httpSession.getAttribute(“uploadedFiles”);
if(上载文件!=null){
uploadedFiles.addAll(Arrays.asList(files));
}否则{
uploadedFiles=Arrays.asList(文件);
}
setAttribute(“uploadedFiles”,uploadedFiles);
返回“重定向:”;
}
}

经过一些调查,我发现只有在Tomcat处理请求时,MultipartFile才存在于临时目录中。在响应之后,它立即删除文件。这就是尺寸为零的原因。可以使用自定义结构将此数据存储在内存、数据库或其他地方

以下是一个例子:

public class UploadedFile {
    private final String originalFilename;
    private final byte[] data;

    public UploadedFile(String fileName, byte[] data) {
        this.originalFilename = fileName;
        this.data = data.clone();
    }

    public String getOriginalFilename() {
        return originalFilename;
    }

    public byte[] getData() {
        return data.clone();
    }

    public int getSize() {
        return data.length;
    }
}
在内存存储的情况下,可以使用MultipartFile类。如果文件未存储在HDD上,只要有参考,它就存在于内存中

以下是应用程序.properties文件的示例:

multipart.file-size-threshold=10Mb
multipart.max-file-size=10Mb
multipart.max-request-size=10Mb
多部分。文件大小阈值强制将所有上传的文件(最大10MB)存储在内存中,而不是硬盘中。默认情况下,它等于0,所有文件都存储在HDD上

我还发现使用HttpSession并不是一个优雅的决定。 @SessionAttributes注释和模型使此解决方案相当清晰

以下是更新的控制器:

@Controller
public class IndexController {
    @RequestMapping("/")
    public String index(Model model, HttpSession httpSession) {
        List<MultipartFile> uploadedFiles = (List<MultipartFile>) httpSession.getAttribute("uploadedFiles");
        model.addAttribute("uploadedFiles", uploadedFiles);
        return "index";
    }

    @RequestMapping(value = "upload", method = RequestMethod.POST)
    public String index(@RequestParam("files") MultipartFile[] files, HttpSession httpSession) {
        List<MultipartFile> uploadedFiles = (List<MultipartFile>) httpSession.getAttribute("uploadedFiles");
        if (uploadedFiles != null) {
            uploadedFiles.addAll(Arrays.asList(files));
        } else {
            uploadedFiles = Arrays.asList(files);
        }
        httpSession.setAttribute("uploadedFiles", uploadedFiles);
        return "redirect:";
    }
}
@Controller
@SessionAttributes(value = {"uploadedFiles"})
public class IndexController {
    @ModelAttribute("uploadedFiles")
    public List<UploadedFile> initUploadedFiles() {
        return new ArrayList<>();
    }

    @RequestMapping("/")
    public String index() {
        return "index";
    }

    @RequestMapping(value = "upload", method = RequestMethod.POST)
    public String index(Model model, @RequestParam MultipartFile[] files, @ModelAttribute("uploadedFiles") List<UploadedFile> uploadedFiles) {
        for (MultipartFile file : files) {
            try {
                uploadedFiles.add(new UploadedFile(file.getOriginalFilename(), file.getBytes()));
            } catch (IOException e) {
                throw new RuntimeException("Can't read file " + file.getOriginalFilename(), e);
            }
        }
        model.addAttribute("uploadedFiles", uploadedFiles);
        return "redirect:";
    }
}
@控制器
@SessionAttributes(值={“uploadedFiles”})
公共类索引控制器{
@ModelAttribute(“上载的文件”)
公共列表initUploadedFiles(){
返回新的ArrayList();
}
@请求映射(“/”)
公共字符串索引(){
返回“索引”;
}
@RequestMapping(value=“upload”,method=RequestMethod.POST)
公共字符串索引(模型模型,@RequestParam MultipartFile[]文件,@ModelAttribute(“uploadedFiles”)列出uploadedFiles){
用于(多部分文件:文件){
试一试{
uploadedFiles.add(新的UploadedFile(file.getOriginalFilename(),file.getBytes());
}捕获(IOE异常){
抛出新的RuntimeException(“无法读取文件”+file.getOriginalFilename(),e);
}
}
model.addAttribute(“uploadedFiles”,uploadedFiles);
返回“重定向:”;
}
}