Java Spring文件上传问题

Java Spring文件上传问题,java,spring,file-upload,spring-mvc,Java,Spring,File Upload,Spring Mvc,我有以下代码块,用于处理我在Spring MVC web应用程序中使用的照片的文件上载。我使用Spring MVC CommonsMultipartFileResolver来处理文件上传 if(model.getPhoto() != null){ if(!model.getPhoto().isEmpty()){ MultipartFile file = model.getPhoto(); String fileName = file.getOriginal

我有以下代码块,用于处理我在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();
         }
    }
}
在我的app-servlet.xml文件中,我有以下代码来配置多部分文件解析器bean

 <bean id="multipartResolver"   class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
 </bean>
我尝试了几个不同的选项来配置多部分解析器,比如将其切换为处理CommonMultipartFile对象,而不是普通的MultipartFile对象,但没有任何改变

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

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

也没有什么变化。就可以上传的文件大小而言,我不确定CommonsMultipartResolver默认值是多少,但这不是我的问题

有人告诉我,我遇到的问题是由于spring使用的多部分解析器/处理程序中的一个问题造成的。我最近有一篇关于这个问题的帖子,由于发现了新信息,我想用新信息重新发布。旧邮件可在以下网址找到:

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

请帮我弄清楚这是怎么回事,如果有更好、更简单的解决方案来解决这些选项,但如果我能找到解决方案,我更愿意使用我目前的方法

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

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

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

还有一个属性maxInMemorySize,允许您在将文件写入磁盘之前指定允许的最大大小。虽然这与最大上载大小的工作方式相同,但如果不指定数量,则默认为1024字节。这可以解释为什么我试图上传一个大文件时会被破坏

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

这就是解决我问题的方法。我在查看CommonFileUpload文档时了解到该属性默认为1024

您可以在以下位置查看此文档:


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

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

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

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

当文件大小太小时,我不会面对这个问题。在“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);
    }
链接:

意见:

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

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

  • 所以我的解决方案是,首先我必须使用“transferTo”方法将其保存在服务器操作中,然后检索该本地文件以进行验证或任何其他第二次需要


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

    Nice find,尽管我觉得这个默认设置不应该导致上传中断。我会向春季男孩们报告一个问题,看看他们对这个问题有什么看法。我会的,我会更深入地研究这个问题。令人惊讶的是,如果没有指定任何内容,但没有指定其他内容,他们会将一个默认值设置为1024。根据您引用的链接,默认值为10240字节(解释您之前的经验结果)。非常感谢您的回答!我也遇到了这些问题。你已经省下了数小时的时间去弄清楚。干杯,这并不能真正回答问题。如果您有不同的问题,可以单击以提问。一旦你有足够的时间,你也可以把更多的注意力放在这个问题上。我不同意这一点。在“CommonsMultipartFile”类中调用“getBytes”方法时会出现此异常。在我的例子中,我使用“transferTo”方法,在这两种情况下,它都将调用方法“isAvailable”。如果我们已经使用该多部分文件的inputstream,则会发生此异常。因此,我的解决方案是,首先我们需要将该文件保存在服务器位置,并让该文件进行任何验证。因为如果超过了这个限制