tomcat Spring MVC文件上载-无法处理部件,因为未提供多部件配置

ekqde3dh  于 2022-11-13  发布在  Spring
关注(0)|答案(9)|浏览(205)

我是Spring的新手,我正在尝试为我的项目上传文件(顺便说一句,我正在使用Spring工具套件),当我提交一个表单时,我得到的是:
HTTP状态500 -无法分析多部分Servlet请求;嵌套的异常是java.lang.IllegalStateException:由于未提供多部件配置,因此无法处理部件
来自浏览器的堆栈跟踪:

type Exception report

message Could not parse multipart servlet request; nested exception is java.lang.IllegalStateException: Unable to process parts as no multi-part configuration has been provided

description The server encountered an internal error that prevented it from fulfilling this request.

exception

org.springframework.web.multipart.MultipartException: Could not parse multipart servlet request; nested exception is java.lang.IllegalStateException: Unable to process parts as no multi-part configuration has been provided
    org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.parseRequest(StandardMultipartHttpServletRequest.java:100)
    org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.(StandardMultipartHttpServletRequest.java:78)
    org.springframework.web.multipart.support.StandardServletMultipartResolver.resolveMultipart(StandardServletMultipartResolver.java:75)
    org.springframework.web.multipart.support.MultipartFilter.doFilterInternal(MultipartFilter.java:108)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:106)
root cause

java.lang.IllegalStateException: Unable to process parts as no multi-part configuration has been provided
    org.apache.catalina.connector.Request.parseParts(Request.java:2676)
    org.apache.catalina.connector.Request.getParts(Request.java:2643)
    org.apache.catalina.connector.RequestFacade.getParts(RequestFacade.java:1083)
    org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.parseRequest(StandardMultipartHttpServletRequest.java:85)
    org.springframework.web.multipart.support.StandardMultipartHttpServletRequest.(StandardMultipartHttpServletRequest.java:78)
    org.springframework.web.multipart.support.StandardServletMultipartResolver.resolveMultipart(StandardServletMultipartResolver.java:75)
    org.springframework.web.multipart.support.MultipartFilter.doFilterInternal(MultipartFilter.java:108)
    org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:106)

note The full stack trace of the root cause is available in the Apache Tomcat/8.0.27 logs.

这是jsp中的表单标记:

<form:form class="form-horizontal" role="form" method="post"
            action="newArtist.html" modelAttribute="artist" enctype="multipart/form-data">

输入部分:

<div class="form-group">
    <div class="col-lg-3">
        <label for="photo">Artist photo:</label>
        <form:input type="file" id="photo" path="photo"></form:input>
    </div>
</div>

照片存储在艺术家对象的此字段中:

@Lob
private byte[] photo;

控制器Map方法:

@RequestMapping(value = "/newArtist", method = RequestMethod.GET)
public String showAddArtistForm(Model model)
{
    model.addAttribute("artist", new Artist());
    return "newArtist";
}

@RequestMapping(value = "/newArtist", method = RequestMethod.POST)
public String addArtist(@ModelAttribute("artist") @Valid Artist artist, BindingResult result,
        @RequestParam("photo") MultipartFile photo) throws IOException
{   
    if (result.hasErrors())
        return "newArtist";

    if(photo.getBytes() != null)
        artist.setPhoto(photo.getBytes());

    artistService.addArtist(artist);

    return "redirect:artists.html";
}

servlet-context.xml中的多部分解析器配置:

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="10000000"/>
</bean>

web.xml中的过滤器:

<filter>
    <filter-name>MultipartFilter</filter-name>
    <filter-class>org.springframework.web.multipart.support.MultipartFilter</filter-class>
</filter>
<filter>
    <filter-name>springSecurityFilterChain</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>MultipartFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
<filter-mapping>
    <filter-name>springSecurityFilterChain</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>

相关性:

<!-- Apache Commons FileUpload -->
    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.3.1</version>
    </dependency>

    <!-- Apache Commons IO -->
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.4</version>
    </dependency>

我还将Tomcat的配置文件context.xml导入到META-INF/context.xml中,并编辑了如下Context标记:

<Context allowCasualMultipartParsing="true">

似乎没有什么工作,任何帮助将不胜感激。

brc7rcf0

brc7rcf01#

实际上,为了用Spring MVC上传多部分文件,你不需要在web.xml上使用任何过滤器。我在我的项目中使用了相同的配置,并且它工作了(${spring.version} = 4.3.4.RELEASE):
聚甲醛

<dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-web</artifactId>
        <version>${spring.version}</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>${spring.version}</version>
    </dependency>

    <!-- Apache Commons FileUpload -->
    <dependency>
        <groupId>commons-fileupload</groupId>
        <artifactId>commons-fileupload</artifactId>
        <version>1.3.2</version>
    </dependency>

    <!-- Apache Commons IO -->
    <dependency>
        <groupId>commons-io</groupId>
        <artifactId>commons-io</artifactId>
        <version>2.5</version>
    </dependency>

HTML语言

<form method="POST" enctype="multipart/form-data" action="uploadAction">
        <table>
            <tr><td>File to upload:</td><td><input type="file" name="file" /></td></tr>
            <tr><td></td><td><input type="submit" value="Upload" /></td></tr>
        </table>
    </form>

Spring上下文

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="10000000"/>
</bean>

Spring控制器

@PostMapping("/uploadAction")
    public String handleFileUpload(@RequestParam("file") MultipartFile file,
            RedirectAttributes redirectAttributes) {

        File out = new File("outputfile.pdf");
        FileOutputStream fos = null;

        try {
            fos = new FileOutputStream(out);

            // Writes bytes from the specified byte array to this file output stream 
            fos.write(file.getBytes());
            System.out.println("Upload and writing output file ok");
        } catch (FileNotFoundException e) {
            System.out.println("File not found" + e);
        } catch (IOException ioe) {
            System.out.println("Exception while writing file " + ioe);
        } finally {
            // close the streams using close method
            try {
                if (fos != null) {
                    fos.close();
                }
            } catch (IOException ioe) {
                System.out.println("Error while closing stream: " + ioe);
            }

            //storageService.store(file);
            redirectAttributes.addFlashAttribute("message",
                    "You successfully uploaded " + file.getOriginalFilename() + "!");

            return "redirect:/";
        }
    }
elcex8rz

elcex8rz2#

所有答案都不能正确解决问题。根据Tomcat documentation,在allowCasualMultipartParsing的配置上:
如果在调用HttpServletRequest.getPart* 或HttpServletRequest.getParameter* 时Tomcat应自动解析multipart/form-data请求正文,则设置为true,即使目标servlet未标记@MultipartConfig注解也是如此(请参见Servlet规范3.0,第3.2节了解详细信息)。请注意,false以外的任何设置都会导致Tomcat的行为方式在技术上不符合规范。预设值为false。
那么,什么是符合规范的方式呢?阅读官方的JEE 6 tutorial会给你一个提示。如果你想在Servlet 3或更新版本中使用符合规范的方式,你的servlet必须有一个MultipartConfig。你有三个选择,这取决于你如何配置servlet:

  • 使用编程配置:context.addServlet(name, servlet).setMultipartConfig(new MultipartConfigElement("your_path") .
  • 使用注解,用@javax.servlet.annotation.MultipartConfig注解servlet的类。
  • 使用XML配置,将以下内容添加到servlet部分的WEB-INF/web.xml描述符中:
<multipart-config>
     <location>/tmp</location>
     <max-file-size>20848820</max-file-size>
     <max-request-size>418018841</max-request-size>
     <file-size-threshold>1048576</file-size-threshold>
</multipart-config>
tsm1rwdh

tsm1rwdh3#

对于那些为PUT方法处理程序获得相同异常的人:请改用POSTPUT与多部分不兼容。
更多详情,请参见respective answer

pdkcd3nj

pdkcd3nj4#

尽管您已经提供了***multipartResolver***bean,但从未找到多部分配置的异常中可以直接看出这一点。
问题在于,在Spring安全性筛选器之前指定MultipartFilter时,它尝试获取***multipartResolver***Bean,但无法找到它。因为它期望Bean名称/ID为***filterMultipartResolver***,而不是***multipartResolver***。
帮你自己一个忙。请更改bean配置,如下所示-

<bean id="filterMultipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <property name="maxUploadSize" value="10000000"/>
</bean>
a7qyws3x

a7qyws3x5#

在配置文件中添加为:

@Bean(name = "multipartResolver")
public CommonsMultipartResolver CanBeAnyName() { 
//configuration

}
7y4bm7vi

7y4bm7vi6#

我有类似的东西,但我所做的只是发送一个文件,而没有将其与我的模型中的任何属性进行Map,在您的情况下,我将修改如下:

<div class="form-group">
    <div class="col-lg-3">
        <label for="photo">Artist photo:</label>
        <input type="file" id="photo" name="file"/>
    </div>
</div>

在控制器中

@RequestMapping(value = "/newArtist", method = RequestMethod.POST)
public String addArtist(@ModelAttribute("artist") @Valid Artist artist, BindingResult result,
    @RequestParam("file") MultipartFile file) throws IOException
//Here read the file and store the bytes into your photo attribute
...
omjgkv6w

omjgkv6w7#

在Sping Boot 应用程序中出现相同的问题时,此异常会发生几次:

  • org.springframework.web.multipart.MultipartException:无法分析多部分servlet请求;嵌套异常为
  • java.lang.IllegalStateException:文件大小限制超出异常:字段multipartFile超出了其允许的最大大小1048576字节

文件大小限制超出异常:字段multipartFile超出了其允许的最大大小1048576字节。
使用以下代码消除tomcat异常,并从http://www.mkyong.com/spring-boot/spring-boot-file-upload-example/复制catting
Tomcat大文件上载连接已重置。需要使{@link #containerCustomizer()}正常工作,否则将多次发生异常,uploadError的RequestMapping将失败。

@Bean
public TomcatEmbeddedServletContainerFactory tomcatEmbedded() {

    TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();

    tomcat.addConnectorCustomizers((TomcatConnectorCustomizer) connector -> {
        if ((connector.getProtocolHandler() instanceof AbstractHttp11Protocol<?>)) {
            //-1 means unlimited
            ((AbstractHttp11Protocol<?>) connector.getProtocolHandler()).setMaxSwallowSize(-1);
        }
    });

    return tomcat;

}
jgzswidk

jgzswidk8#

如果有人使用J2EE而不是Spring框架,并且仍然面临问题
您可以尝试在servlet上添加@MultipartConfig注解,并在表单标记内添加enctype="multipart/form-data"

b1payxdu

b1payxdu9#

如果您使用的是Tomcat 8。
在Tomcat的conf/context.xml中配置以下内容

  • 将allowCasualMultipartParsing=“true”属性添加到上下文节点
  • 在上下文节点内添加

相关问题