0

I am trying to send a multipart request to the server but i am getting the following exception

org.springframework.web.multipart.MultipartException: Current request is not a multipart request
    at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue(RequestParamMethodArgumentResolver.java:188)
    at org.springframework.web.method.annotation.AbstractNamedValueMethodArgumentResolver.resolveArgument(AbstractNamedValueMethodArgumentResolver.java:104)
    at org.springframework.web.method.support.HandlerMethodArgumentResolverComposite.resolveArgument(HandlerMethodArgumentResolverComposite.java:121)
    at org.springframework.web.method.support.InvocableHandlerMethod.getMethodArgumentValues(InvocableHandlerMethod.java:161)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:128)

Basing on tutorials and stackoverflow questions i have developped the folowing code

Controller

  @RequestMapping(value = "/upload-file", method = RequestMethod.POST)
    public ResponseEntity<Void> getUploadFile(@RequestParam("file") MultipartFile file) {
    LOGGER.debug(String.valueOf(file));}

MultipartConfiguration

@Configuration
@EnableWebMvc
public class MultipartConfiguration {

    private static final String DEFAULT_ENCODING = "UTF-8";

    private static final long MAX_UPLOAD_FILE_SIZE = 100000000;

    @Bean
    public CommonsMultipartResolver multipartResolver() {
        CommonsMultipartResolver resolver=new CommonsMultipartResolver();
        resolver.setDefaultEncoding("utf-8");
        resolver.setMaxUploadSize(MAX_UPLOAD_FILE_SIZE);
        resolver.setDefaultEncoding(DEFAULT_ENCODING);
        return resolver;
    }
}

html

<input type="file"  style="display:none" #fileupload name="image" (change)="fileProgress($event)" />

Component

export class FileUploadComponent {
  fileData: any = null;
  uploadedFilePath: string = null;
   formData = new FormData();
    reader = new FileReader();
  @Output() fiLoaded: EventEmitter<File> = new EventEmitter();
  constructor(private pointeService: PointeService) { }

  fileProgress(fileInput: any) {

    this.fileData = fileInput.target.files[0];

    this.reader.readAsDataURL(this.fileData);
    this.reader.onloadend = (_event) => {
      this.formData.append('file', this.fileData);
      this.onFileLoaded(this.formData);
    };
  }

  onFileLoaded(formData: any) {
    this.pointeService.postModifiedFileExel(formData)
      .subscribe(events => {
        if (events.type === HttpEventType.UploadProgress) {
        } else if (events.type === HttpEventType.Response) {
         // this.fileUploadProgress = 0;
          console.log(events.body);
          alert('SUCCESS !!');
        }

      });
  }
}

Service

postModifiedFileExel(formData: any) {
    return this.http.post(`${AppUtils.REST_API_SERVER}/espacegroupe/upload-file`, formData ,  {
      reportProgress: true,
      observe: 'events'
    });
  }

I also noticed that my post contains just the name of the file and it does not cotains data in byte format

enter image description here

Any suggestions please?

BELLIL
  • 739
  • 10
  • 23

1 Answers1

0

For those who still stuck in the same issue, i will first explain how i debugged to find out the solution, and second what i was doing wrong.

Debugging

When i flowed the stack trace i found two methods that are responsible for the message that i receive i.e Current request is not a multipart request

public class ServletFileUpload extends FileUpload {
        private static final String POST_METHOD = "POST";

        public static final boolean isMultipartContent(HttpServletRequest request) {
            return !"POST".equalsIgnoreCase(request.getMethod()) ? false : FileUploadBase.isMultipartContent(new ServletRequestContext(request));
        }
      .....
}

and

    public abstract class FileUploadBase {

        public FileUploadBase() {
        }

        public static final boolean isMultipartContent(RequestContext ctx) {
            String contentType = ctx.getContentType();
            if (contentType == null) {
                return false;
            } else {
                return contentType.toLowerCase(Locale.ENGLISH).startsWith("multipart/");
            }
        }
     ....
}

This means that if your call is different of POST or your content type does not start with "multipart/" your playload is considered as a non multipart

and i noticed that my content Type was alway Content-Type: application/json

But why do i always have Content-Type: application/json althought formData is supposed to be Content-Type: multipart/form-data ?

In my case it was because in the application there is an url interceptor that always sets in the header Content-Type: application/json.

const authReq = req.clone({setHeaders: {'Content-Type': 'application/json'}, withCredentials: true});

To be sure that you send the right data type, be sure that in request Header you have Content-Type: multipart/form-data;boundary=... and that your formData is in binary.

enter image description here

Here there is a link to the article that helped me to resolve this issue

BELLIL
  • 739
  • 10
  • 23