upload file springboot Required request part 'file' is not present
Asked Answered
D

10

48

I want to add an upload function to my spring boot application; this is my upload Rest Controller

package org.sid.web;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.ArrayList;
import java.util.List;

import javax.servlet.ServletContext;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;
import org.springframework.core.env.Environment;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.sid.entities.FileInfo;

@RestController
public class UploadController {
  @Autowired
  ServletContext context;

  @RequestMapping(value = "/fileupload/file", headers = ("content-type=multipart/*"), method = RequestMethod.POST, consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
  public ResponseEntity<FileInfo> upload(@RequestParam("file") MultipartFile inputFile) {
    FileInfo fileInfo = new FileInfo();
    HttpHeaders headers = new HttpHeaders();
    if (!inputFile.isEmpty()) {
      try {
        String originalFilename = inputFile.getOriginalFilename();
        File destinationFile = new File(
            context.getRealPath("C:/Users/kamel/workspace/credit_app/uploaded") + File.separator + originalFilename);
        inputFile.transferTo(destinationFile);
        fileInfo.setFileName(destinationFile.getPath());
        fileInfo.setFileSize(inputFile.getSize());
        headers.add("File Uploaded Successfully - ", originalFilename);
        return new ResponseEntity<FileInfo>(fileInfo, headers, HttpStatus.OK);
      } catch (Exception e) {
        return new ResponseEntity<FileInfo>(HttpStatus.BAD_REQUEST);
      }
    } else {
      return new ResponseEntity<FileInfo>(HttpStatus.BAD_REQUEST);
    }
  }
}

but when testing this in postman with inserting http://localhost:8082/fileupload/file and adding a file to the body i got this error: "exception": org.springframework.web.multipart.support.MissingServletRequestPartException", "message": "Required request part 'file' is not present,

Delve answered 12/5, 2017 at 11:9 Comment(2)
may be this will help #43865326Gae
Unfortunely this does not solve my problem. The error still appearingDelve
F
41

This is how your request in Postman should look like:

enter image description here

My sample code:

application.properties

#max file and request size 
spring.http.multipart.max-file-size=10MB
spring.http.multipart.max-request-size=11MB

Main Application Class:

Application.java

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {

    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Rest controller class:

import org.springframework.http.MediaType;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.multipart.MultipartFile;


    @Controller
    @RequestMapping("/fileupload")
    public class MyRestController {

    @RequestMapping(value = "/file", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
        public @ResponseBody String myService(@RequestParam("file") MultipartFile file,
                @RequestParam("id") String id) throws Exception {

    if (!file.isEmpty()) { 

           //your logic
                        }
return "some json";

                }
    }

pom.xml

//...

<parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.5.2.RELEASE</version>
        <relativePath /> <!-- lookup parent from repository -->
    </parent>

....



<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web-services</artifactId>
</dependency>

//...
Floriated answered 13/5, 2017 at 10:43 Comment(10)
I'm trying the same test but i pass file as key and choose a file but the error is still there. That why i'm so confusedDelve
I've added this to my app file : @Bean public CommonsMultipartResolver multipartResolver() { CommonsMultipartResolver multipart = new CommonsMultipartResolver(); multipart.setMaxUploadSize(3 * 1024 * 1024); return multipart;} @Bean @Order(0) public MultipartFilter multipartFilter() { MultipartFilter multipartFilter = new MultipartFilter(); multipartFilter.setMultipartResolverBeanName("multipartReso‌​lver"); return multipartFilter; } Delve
Yes it did, because I have worked on this before using spring boot.Floriated
@TanmayPlease can you show me your code because really i dont get this error. I've been blockin' on this for two weeks and i need this rest controller for my angular2 frontend partDelve
Thanks @Tanmay i'm waitingDelve
It's working now i just changed the head of the function, really i'm so grateful for your help. thanksDelve
@Tanmay Delhikar I have more or less your same sample client, and I am trying to write an integration test, unsuccessfully, since I have the same exception posted in this question: "org.springframework.web.multipart.support.MissingServletRequestPartException", "message": "Required request part 'file' is not present" Can you kindly write a simple example on how to invoke that WS?Gaiseric
In my case it was the @Bean of MultipartResolver. Simply removed it and that did the work.Tolbutamide
Thank you very much. It worked and seems like I wasn't giving the key name in RequestParam. It should be like this: @RequestParam("file") DataType variableSemiliquid
@Gaiseric in my case it works in mvc test if I don't specify any explicit bean for MultipartResolver and if I use file as name for the multipart data in test: final var file = new MockMultipartFile("file", "filename.exe", "application/vnd.microsoft.portable-executable", "not suspicious".getBytes()); See: https://mcmap.net/q/150872/-using-spring-mvc-test-to-unit-test-multipart-post-requestDeduce
G
17

In your method you have specified like this
@RequestParam("file"). Hence it is expecting the key to be file. It is quite evident in the exception message. Use this name in the Key field in Postman when you upload file.
More information here integration test case and file upload

Gae answered 12/5, 2017 at 12:17 Comment(1)
thanks for your help, but unfortunely thats what i was doing. I passed file as a key and upload the file and it's not working.Delve
R
13

I also had similar issue and was getting the error request part file not present. But I later realized that I have this code in my application which was causing problem:

@Bean(name = "multipartResolver")
    public CommonsMultipartResolver multipartResolver() {
        CommonsMultipartResolver multipartResolver = new 
        CommonsMultipartResolver();
        multipartResolver.setMaxUploadSize(1000000000);
        return multipartResolver;
      }

I removed this and it started working for both RequestPart and RequestParam. See the related issue below:

https://forum.predix.io/questions/22163/multipartfile-parameter-is-not-present-error.html

Rasberry answered 21/2, 2019 at 15:16 Comment(2)
I had similar problem, probably the Bean I had worked on previous Spring release; with 1.5.15 I had to remove it.Generation
By removing this config works for me. I use spring-boot-2.0.2Emotive
S
9

Except for other posted answers, the problem might be realated to missing multipart support for the servlet handling the request (spring's DispatcherServlet in case of Spring's app).

This can be fixed by adding multipart support to dispatcher servlet in web.xml declaration or during initialization (in case of annotation-based config)

a) web-xml based config

<web-app xmlns="http://java.sun.com/xml/ns/javaee"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
          http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
          version="3.0">

 <servlet>
   <servlet-name>dispatcher</servlet-name>
   <servlet-class>
     org.springframework.web.servlet.DispatcherServlet
   </servlet-class>
   <init-param>
     <param-name>contextConfigLocation</param-name>
     <param-value>/WEB-INF/spring/dispatcher-config.xml</param-value>
   </init-param>
   <load-on-startup>1</load-on-startup>
   <multipart-config>
        <max-file-size>10485760</max-file-size>
        <max-request-size>20971520</max-request-size>
        <file-size-threshold>5242880</file-size-threshold>
    </multipart-config>
 </servlet>

</web-app>

b) for annotation-based configuration this would be following:

public class AppInitializer implements WebApplicationInitializer { 

@Override 
public void onStartup(ServletContext servletContext) { 
    final AnnotationConfigWebApplicationContext appContext = new AnnotationConfigWebApplicationContext(); 

    final ServletRegistration.Dynamic registration = servletContext.addServlet("dispatcher", new DispatcherServlet(appContext)); 
    registration.setLoadOnStartup(1); 
    registration.addMapping("/"); 

    File uploadDirectory = new File(System.getProperty("java.io.tmpdir"));                  
    MultipartConfigElement multipartConfigElement = new  MultipartConfigElement(uploadDirectory.getAbsolutePath(), 100000, 100000 * 2, 100000 / 2); 

    registration.setMultipartConfig(multipartConfigElement);
} }

Then we need to provide multipart resolver which can resolve files sent as multipart-request. For annotation config this can be done in following way:

@Configuration
public class MyConfig {

@Bean
public MultipartResolver multipartResolver() {
    return new StandardServletMultipartResolver();
}
}

For xml-based spring configuration you need to add this bean to the context via tag declaration declaration:

<bean id="multipartResolver" class="org.springframework.web.multipart.support.StandardServletMultipartResolver" /> 

Alternatively to spring's standard multipart resolver you can use implementation from commons. This way however extra dependency is required:

<dependency>
  <groupId>commons-fileupload</groupId>
  <artifactId>commons-fileupload</artifactId>
  <version>1.3.3</version>
</dependency>

<bean id="multipartResolver" class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
<property name="maxUploadSize" value="100000000"/>
</bean>
Sinus answered 28/11, 2017 at 9:47 Comment(1)
This answer helped me to solve the problem, Thanks alotJugurtha
F
1

Use @RequestPart("file") instead of @RequestParam("file").

Farcy answered 2/7, 2023 at 15:2 Comment(0)
D
1

Thanks, @Eyoab, it works for me.

I had the same problem with feign client. I have one endpoint to upload a file that accepts the Multipart file.

Main upload endpoint

I was calling the above endpoint using feign client. (feign client method)

feign client caller method

Now, you can see in the first image, the endpoint accepts the file as a @RequestParam. and in the second image I use @RequestPart in my feign client call. I helps me to resolve the issue.

Deluna answered 27/7, 2023 at 7:46 Comment(0)
D
0

I had similar issue with error Could not resolve parameter [0] in public org.springframework.http.ResponseEntity... Required request part 'file' is not present and tried many things but one change resolved this issue.

Had to update

// old
@RequestParam("file") MultipartFile inputFile


// new
@RequestParam(value = "file") MultipartFile inputFile
Dowser answered 14/9, 2022 at 21:32 Comment(0)
N
0

In my case, i have multi module project as;

core > api > admin

Admin and api are parent of core module.

Core/ImageController:

@RequestMapping(value = "/upload/image", method = RequestMethod.POST)
    public ResponseEntity uploadBanner(@RequestParam(value = "file", required = 
 false) MultipartFile bannerFile){...}

AdminApplicationInitializer:

@Override
protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
    return application.sources(AdminApplicationInitializer.class);
}

@Bean
public MultipartResolver multipartResolver() {
    CommonsMultipartResolver resolver = new CommonsMultipartResolver();
    //100MB
    resolver.setMaxUploadSize(100 * (long) 1024 * 1024);
    return resolver;
}

@Bean
public MultipartConfigElement multipartConfigElement() {
    MultipartConfigFactory factory = new MultipartConfigFactory();
    factory.setMaxFileSize(DataSize.ofMegabytes(200L));
    factory.setMaxRequestSize(DataSize.ofMegabytes(200L));
    return factory.createMultipartConfig();
}

When i tried to upload file from api module with core service "/upload/image". I had get an error : "Required request part 'file' is not present". Cause of ApiInitializer had not configuration like AdminInitializer.

The Solution : i added multipartResolver() and multipartConfigElement() method to ApiApplicationInitializer.Then it worked.

Nianiabi answered 21/10, 2022 at 7:24 Comment(0)
F
0

I also faced this issue. My code is as follows:

@PostMapping("/process_contact")
    public String processContact(@ModelAttribute Contact contact, @RequestParam MultipartFile file,
            Principal p ) {
        try {
        String name=p.getName();
        User user=this.userRepository.getUserByUserName(name);
        
        //processing and uploading file
        if(file.isEmpty()) {
            System.out.println("Please Upload image");
        }
        else {
            contact.setC_imageUrl(file.getOriginalFilename());
            File saveFile=new ClassPathResource("static/image").getFile();
            Path path=Paths.get(saveFile.getAbsolutePath()+File.separator+file.getOriginalFilename());
            Files.copy(file.getInputStream(), path, StandardCopyOption.REPLACE_EXISTING);
            System.out.println("Image is uploaded");
        }
        
        
        user.getContacts().add(contact);
        contact.setUser(user);
        this.userRepository.save(user);
        System.out.println("Data" + contact);
        }catch(Exception e) {
            System.out.println("Error"+e.getMessage());
            e.printStackTrace();
        }
        return "add_contact";
    }

Then a have add a property to my application.properties file:

spring.servlet.multipart.enabled=true

and my error is resolved.

Fossiliferous answered 2/11, 2023 at 7:52 Comment(1)
As it’s currently written, your answer is unclear. Please edit to add additional details that will help others understand how this addresses the question asked. You can find more information on how to write good answers in the help center.Fruition
O
0

We are using PrimeFaces and file upload there (so we have apache commons-fileupload library in pom). And this was reason why Spring (5.3; SpringBoot 2.7) multipart file upload was not working (getting 400 Bad Request). To make file upload working in both frameworks (GUI & REST) we had to:

  1. Add MultipartFilter (org.springframework.web.multipart.support.MultipartFilter) to the Application.java
  2. Set highest precedence (@Order(0) & setOrder(0))
  3. But also set url patterns (so commons-fileupload will not be "bypassed")

Application.java

private static final String DEFAULT_SPRING_5_MULTIPART_RESOLVER_BEAN_NAME = "multipartResolver";
public static final String REST_PATH = "/your/rest/path/*";

@Bean
@Order(0)
public FilterRegistrationBean<MultipartFilter> multipartFilter() {
        FilterRegistrationBean<MultipartFilter> registrationBean = new FilterRegistrationBean<>();
        MultipartFilter multipartFilter = new MultipartFilter();
        multipartFilter.setMultipartResolverBeanName(DEFAULT_SPRING_5_MULTIPART_RESOLVER_BEAN_NAME);

        registrationBean.setFilter(multipartFilter);
        registrationBean.setOrder(0);
        registrationBean.addUrlPatterns(REST_PATH);
        return registrationBean;
}

Rest controller (based on paragraph 3 of Multipart Request Handling in Spring)

@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public String uploadFileWithObject(@RequestPart("file") MultipartFile file, @RequestPart("employee") Employee employee) {
        return "Ok";
}

enter image description here

Content of the employee "Value":

{
    "name" : "john"
}
Offend answered 20/2 at 12:59 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.