Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring MVC file upload - Unable to process parts as no multi-part configuration has been provided

So I'm a newbie to Spring and I'm trying to get file upload working for my project (I'm using Spring Tool Suite btw.) and when submitting a form all I'm getting is:

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

Stack trace from browser:

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.

This is the form tag in jsp:

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

Input part:

<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>

Photo is stored in this field in Artist object:

@Lob
private byte[] photo;

Controller mapping methods:

@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";
}

Multipart resolver configuration in servlet-context.xml:

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

Filters in 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>

Dependencies:

<!-- 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>

I also imported Tomcat's config file context.xml to META-INF/context.xml and edited Context tag like so:

<Context allowCasualMultipartParsing="true">

Nothing seems to be working, any help will be greatly appreciated.

like image 909
kbijoch Avatar asked Jun 20 '16 12:06

kbijoch


People also ask

How do I upload a file to spring boot?

Spring Boot file uploader Create a Spring @Controller class; Add a method to the controller class which takes Spring's MultipartFile as an argument; Save the uploaded file to a directory on the server; and. Send a response code to the client indicating the Spring file upload was successful.

What is the role of multipart resolver and when is it used?

MultipartResolver interface is used for uploading files – CommonsMultipartResolver and StandardServletMultipartResolver are two implementations provided by spring framework for file uploading.

What is multipart Spring?

Multipart requests consist of sending data of many different types separated by a boundary as part of a single HTTP method call. Generally, we can send complicated JSON, XML, or CSV data, as well as transfer multipart file(s) in this request. Examples of multipart files include audio or image files.


1 Answers

None of the answers address the issue properly. As per Tomcat documentation, on the configuration of allowCasualMultipartParsing:

Set to true if Tomcat should automatically parse multipart/form-data request bodies when HttpServletRequest.getPart* or HttpServletRequest.getParameter* is called, even when the target servlet isn't marked with the @MultipartConfig annotation (See Servlet Specification 3.0, Section 3.2 for details). Note that any setting other than false causes Tomcat to behave in a way that is not technically spec-compliant. The default is false.

So, what's the compliant way? Reading the official JEE 6 tutorial gives a hint. If you want to use a spec-compliant way with Servlet 3 or newer, your servlet must have a MultipartConfig. You have three choices, depending on how you configure your servlet:

  • With programmatic configuration: context.addServlet(name, servlet).setMultipartConfig(new MultipartConfigElement("your_path").
  • With annotations, annotate the servlet's class with @javax.servlet.annotation.MultipartConfig.
  • With XML configuration, add this to the WEB-INF/web.xml descriptor, in the section of your servlet:

    <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>
    
like image 179
Martín Straus Avatar answered Sep 18 '22 15:09

Martín Straus