0

I have an Java application running Spring and on it I have an endpoint to receive multiple files but, every time I hit it I get "415 Status".

This is my endpoint:

@PostMapping(value = "/upload", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public List<Media> uploadMediaToS3(@RequestPart("files") Set<MultipartFile> files,
                                   @RequestPart("mediaUploads") Set<MediaUploadDTO> mediaUploadDTOs,
                                   @RequestParam("profileId") UUID profileId) throws IOException, FindMeDataNotFoundException {
    logger.info("WORKED! " + profileId.toString());
    return new ArrayList<>();
}

And this is how I'm building the request on my Angular application: PS: postMedia is an array of { fileData: fileToSend, base64: event.target!.result!.toString() }.

    let formDataWithFiles = new FormData();
    let filesRaw = [] as Array<File>;
    let filesInfo = [] as Array<Media>;
    this.postMedias.forEach(postMedia => {
      filesRaw.push(new File([postMedia.base64], postMedia.fileData.fileName));
      filesInfo.push(postMedia.fileData);
    });
    formDataWithFiles.append('files', new Blob(filesRaw));
    formDataWithFiles.append('mediaUploads', JSON.stringify(filesInfo));
    console.log(formDataWithFiles);
    this.postService.uploadMedias(formDataWithFiles, this.profileId);

The service call is:

  uploadMedias(files: FormData, profileId: string) {
return firstValueFrom(this.appService.POST<Media>(`medias/upload?profileId=${profileId}`, files)).then(savedMedia => {
  return savedMedia;
}, error => {
  throw error;
});

} My files are being upload to my Angular application by an Input type file and are being save onto a variable by using this code:

if (file.target.files[0]['size'] / 1e+6 == this.maxMediaSize) {
  this.openSnackBar(this.translateService.instant('CUSTOM-FILE-INPUT.MAX-SIZE-ERROR') + `${this.maxMediaSize}Mb`, 2500);
} else {
  let reader = new FileReader();
  reader.readAsDataURL(file.target.files[0]);
  let fileToSend: Media = {} as Media;
  fileToSend.mediaExtension = file.target.files[0].type.substring(file.target.files[0].type.indexOf('/') + 1).toUpperCase();
  fileToSend.mediaPrivacy = 'PUBLIC';
  fileToSend.mediaPrice = 0.0
  fileToSend.whenToDelete = new Date().getTime();
  fileToSend.fileName = file.target.files[0].name;
  fileToSend.mediaType = 'PROFILE_AVATAR_MEDIA';

  reader.onload = (event) => {
    this.formFiles.push({ fileData: fileToSend, base64: event.target!.result!.toString() });
  };
 }

I tried using Postman to test this endpoint but, getting nowhere either: Response of Postman request

I have another endpoint that saves a single file and it works perfectly:

@PostMapping(value = "/update-avatar", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
public Media uploadAvatarToS3(@RequestPart("avatar") MultipartFile avatar,
                              @RequestPart("mediaUpload") MediaUploadDTO mediaUploadDTO,
                              @RequestParam("profileId") UUID profileId) throws IOException, FindMeDataNotFoundException {
    return mediaService.uploadAvatar(avatar, profileId, mediaUploadDTO);
}

My application.properties has the "multipart" properties in it:

spring.servlet.multipart.enabled=true
spring.servlet.multipart.location=${java.io.tmpdir}
spring.servlet.multipart.max-file-size=100MB
spring.servlet.multipart.max-request-size=100MB

My Spring version is 3.3.3 with Java 17

If anyone has any idea on what I could try, it'd help a lot! Thanks in advance!

1 Answer 1

0

Got it working by making some changes: On my Back end, I had to change the Set<MultipartFile> medias to MultipartFile[] medias, then it was able to give me more than just a 415 code. After that, I changed the front-end to this:

          this.postMedias.forEach(postMedia => {
            formDataWithFiles.append('medias', new File([base64ToFile(postMedia.base64)], postMedia.fileData.fileName));
            filesInfo.push(postMedia.fileData);
          });
          formDataWithFiles.append('mediaUploads', new Blob([JSON.stringify(filesInfo)], { type: 'application/json' }));
          this.postService.uploadMedias(formDataWithFiles, this.cookieService.get('ProfileId'), result.id).then(result => {
            this.loadPosts();
          });

I forgot to actually parse the Base64 to file using base64ToFile, after that it worked perfectly.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.