Java Spring FileUpload 的问题

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3747430/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 04:17:59  来源:igfitidea点击:

Problem with Spring FileUpload

javaspringfile-uploadspring-mvc

提问by TheJediCowboy

I have the following block of code which is handling my file upload of a photo that I am using in my Spring MVC web application. I am using Spring MVC CommonsMultipartFileResolver to handle file uploads.

我有以下代码块,用于处理我在 Spring MVC Web 应用程序中使用的照片的文件上传。我正在使用 Spring MVC CommonsMultipartFileResolver 来处理文件上传。

if(model.getPhoto() != null){
    if(!model.getPhoto().isEmpty()){
        MultipartFile file = model.getPhoto();
        String fileName = file.getOriginalFilename();
        String filePath = baseDirectory + fileName;
        FileOutputStream fos = new FileOutputStream(filePath);
         try 
         {
            fos.write(file.getBytes());
            agentProfile.setPhotoUri(fileName);
         } 
         catch (IllegalStateException e) 
         {
            System.out.println(e);

         }
         finally   
         {
             fos.close();
         }
    }
}

In my app-servlet.xml file I have the following code to configure the MultipartFile resolver bean.

在我的 app-servlet.xml 文件中,我有以下代码来配置 MultipartFile 解析器 bean。

 <bean id="multipartResolver"   class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
 </bean>

I am experiencing some random problems when I am uploading photos.

我在上传照片时遇到一些随机问题。

1)If I go to upload a smaller photo, around 3 kb or so, It will upload successfully.

1)如果我去上传一个较小的照片,大约3kb左右,它会上传成功。

2)If I go to upload a little larger photo, it will create the file in the directory, but with a size of 0 bytes and will give the following error message.

2)如果我去上传大一点的照片,它会在目录中创建文件,但大小为0字节,并会给出以下错误消息。

 java.lang.IllegalStateException: File has been moved - cannot be read again
org.springframework.web.multipart.commons.CommonsMultipartFile.getBytes(CommonsMultipartFile.java:112)
com.mmz.admin.mvc.controller.AddAgentController.processFinish(AddAgentController.java:145)
org.springframework.web.servlet.mvc.AbstractWizardFormController.validatePagesAndFinish(AbstractWizardFormController.java:642)
org.springframework.web.servlet.mvc.AbstractWizardFormController.processFormSubmission(AbstractWizardFormController.java:492)
org.springframework.web.servlet.mvc.AbstractFormController.handleRequestInternal(AbstractFormController.java:265)
org.springframework.web.servlet.mvc.AbstractController.handleRequest(AbstractController.java:153)
org.springframework.web.servlet.mvc.SimpleControllerHandlerAdapter.handle(SimpleControllerHandlerAdapter.java:48)
org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:874)
org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:808)
org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:476)
org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:441)
javax.servlet.http.HttpServlet.service(HttpServlet.java:637)
javax.servlet.http.HttpServlet.service(HttpServlet.java:717)

I have tried a couple different options configuring the Multipart resolver such as switching it to handle a CommonsMultipartFileobject as oppose to a plain MultipartFileobject, but nothing changed.

我尝试了几个不同的选项来配置 Multipart 解析器,例如将其切换为处理CommonsMultipartFile对象,而不是普通的MultipartFile对象,但没有任何改变。

I have also tried to manuall configure the maximum upload size in the CommonsMultipartFileResolver bean with the following property.

我还尝试使用以下属性在 CommonsMultipartFileResolver bean 中手动配置最大上传大小。

 <property name="maxUploadSize" value="1024000000"/>  

nothing changed as well. I am not sure what the CommonsMultipartResolver defaults to as far as size of the file that can be uploaded, but that is not my question.

也没有任何改变。我不确定 CommonsMultipartResolver 可以上传的文件大小的默认值,但这不是我的问题。

I have been told that the problem I am experiencing is due to a problem in the Multipart parser/handler that spring is using. I had a recent post about this same problem, and because new information was found, wanted to repost with the new information. The old post can be found at CommonsMultipartFileResolver Problem

有人告诉我,我遇到的问题是由于 spring 使用的 Multipart 解析器/处理程序中的问题。我最近有一篇关于同样问题的帖子,因为发现了新信息,想用新信息重新发布。旧帖子可以在CommonsMultipartFileResolver Problem找到

I feel that I have checked nearly every resource on the internet to find additional documentation, but am unable to figure out the problem.

我觉得我已经检查了互联网上的几乎所有资源以找到其他文档,但我无法找出问题所在。

Please help me figure out what is going on with this, and if there is a better, simplersolution to maybe explorer those options, but I would prefer to stay with my current method if I can find a solution.

请帮助我弄清楚这是怎么回事,如果有更好、更简单的解决方案来探索这些选项,但如果我能找到解决方案,我更愿意保持当前的方法。

EDITNote- I have been experimenting with different size photos to upload, and I believe that the limit that it is allowing me to upload is around 10Kb. Anything larger then 10Kb is causing it to break and give me the error above.

编辑注意 - 我一直在尝试上传不同大小的照片,我相信它允许我上传的限制约为 10Kb。任何大于 10Kb 的东西都会导致它损坏并给我上面的错误。

采纳答案by TheJediCowboy

After doing a lot of research, I solved my problem. It turns out that there is not a default limit set for the maximum amount of bytes that you can upload using CommonsMultipartFileResolverOf course you can specify in your bean whatever you want for this amount by setting the following property.

经过大量研究,我解决了我的问题。事实证明,没有为您可以使用CommonsMultipartFileResolver上传的最大字节数设置默认限制。当然,您可以通过设置以下属性在 bean 中指定任何您想要的字节数。

<property name="maxUploadSize" value="99999999999"/>

There is also a property maxInMemorySizethat allows you to specify the maximum size allowed before files are written to disk. Although this works the same way as the max upload size, if you do not specify an amount, it defaults to 1024 bytes. This would explain it breaking if I attempted to upload a large file.

还有一个属性maxInMemorySize允许您指定在将文件写入磁盘之前允许的最大大小。尽管这与最大上传大小的工作方式相同,但如果您不指定数量,则默认为 1024 字节。如果我尝试上传大文件,这将解释它会中断。

In order to allow files above 1024 bytes to be uploaded, you need to increase the maxInMemorySize value to whatever you need like the following...

为了允许上传 1024 字节以上的文件,您需要将 maxInMemorySize 值增加到您需要的任何值,如下所示...

This is what took care of my problem. I learned that this property defaults to 1024 when I was reviewing documentation for CommonsFileUpload Documentation.

这就是解决我的问题的原因。我在查看 CommonsFileUpload 文档的文档时了解到此属性默认为 1024。

You can view this documentation at CommonsFileUpload Documentation

您可以在CommonsFileUpload 文档中查看此文档

I hope this helps anybody, as there is not very good documentation on using CommonsMultipartFile.

我希望这对任何人都有帮助,因为没有关于使用 CommonsMultipartFile 的很好的文档。

回答by splashout

I notice this error only occurs when the file is over 1024 bytes AND you try to read the file twice. As CitadelCSAlum mentions, setting maxInMemorySize = maxUploadSize will fix this issue, but one should keep in mind memory usage. If memory is a concern, another option is to write the multipart file data to a temp file on the first read and use that file for subsequent reads. If you don't read the twice you should not need to increase maxInMemorySize.

我注意到此错误仅在文件超过 1024 字节并且您尝试读取文件两次时发生。正如 CitadelCSAlum 所提到的,设置 maxInMemorySize = maxUploadSize 将解决这个问题,但应该记住内存使用情况。如果内存是一个问题,另一种选择是在第一次读取时将多部分文件数据写入临时文件,并使用该文件进行后续读取。如果您不读两次,则不需要增加 maxInMemorySize。

回答by Arosha

The exception you reference in your question states: "File has been moved - cannot be read again". This is because we are trying to read inputstream more than one time from multipart file.

您在问题中引用的异常指出:“文件已被移动 - 无法再次读取”。这是因为我们试图从多部分文件中多次读取输入流。

I also faced this issue at one time, and in my case, first I validated the content of the file, and after that I tried to save it using "transferTo" method in Spring MultiPart. This exception comes when I try to use "transferTo" method. Here I am calling for inputstream twice.

我曾经也遇到过这个问题,就我而言,首先我验证了文件的内容,然后我尝试使用 Spring MultiPart 中的“transferTo”方法保存它。当我尝试使用“transferTo”方法时会出现此异常。在这里,我两次调用 inputstream。

I do not face this issue when file size is too small. In "transferTo" method there is an internal call for "isAvailable" method. Please follow the code segment below:

当文件太小时,我不会遇到这个问题。在“transferTo”方法中有对“isAvailable”方法的内部调用。请遵循以下代码段:

    protected boolean More ...isAvailable() {
            // If in memory, it's available.
        if (this.fileItem.isInMemory()) {
            return true;
        }
        // Check actual existence of temporary file.
        if (this.fileItem instanceof DiskFileItem) {
            return ((DiskFileItem) this.fileItem).getStoreLocation().exists();
        }
        // Check whether current file size is different than original one.
        return (this.fileItem.getSize() == this.size);
    }

link: http://grepcode.com/file/repo1.maven.org/maven2/org.springframework/spring-web/3.2.1.RELEASE/org/springframework/web/multipart/commons/CommonsMultipartFile.java#CommonsMultipartFile.isAvailable%28%29

链接:http: //grepcode.com/file/repo1.maven.org/maven2/org.springframework/spring-web/3.2.1.RELEASE/org/springframework/web/multipart/commons/CommonsMultipartFile.java#CommonsMultipartFile。可用%28%29

Observations:

观察:

  1. If it is too small, spring save it in memory and when we ask for the file it retrive from memory. We can ask for it multiple times because file is in memory.

  2. If it is large enough, Spring will save it as a temporary file which we do not know the location, but after we read inputstream once that file may be deleted internally by Spring. Then when we ask for the second time that error says "cannot be read again".

  1. 如果它太小,spring 将其保存在内存中,当我们请求文件时,它会从内存中检索。我们可以多次请求它,因为文件在内存中。

  2. 如果它足够大,Spring会将它保存为一个我们不知道位置的临时文件,但在我们读取输入流后,该文件可能会被Spring内部删除。然后当我们第二次询问时,该错误显示“无法再次读取”。

So my solution is first I have to save it in server loaction using "transferTo" method and retrive that local file to validate or any other second time need.

所以我的解决方案是首先我必须使用“transferTo”方法将它保存在服务器位置并检索该本地文件以进行验证或任何其他第二次需要。

I think it is not good to increase "maxUploadSize" in "multipartResolver" bean as it consumes more memory if the file is too large.

我认为在“multipartResolver”bean 中增加“maxUploadSize”并不好,因为如果文件太大,它会消耗更多内存。