13

I am trying to get my file upload functionality done using Angular2 and SpringBoot. I can certify that my java code for the file uploading working fine since I have tested it successfully using Postman.

However, when it comes to sending the file from Angular2 front end, I am getting the HTTP 400 response saying Required request part 'file' is not present.

This is how I send the POST request from Angular2.

savePhoto(photoToSave: File) {

    let formData: FormData = new FormData();
    formData.append('file', photoToSave);

    // this will be used to add headers to the requests conditionally later using Custom Request Options
    this._globals.setRequestFrom("save-photo");


    let savedPath = this._http
        .post(this._endpointUrl + "save-photo", formData)
        .map(
        res => {
            return res.json();
        }
        )
        .catch(handleError);

    return savedPath;

}

Note that I have written a CustomRequestOptions class which extends BaseRequestOptions in order to append Authorization header and Content Type header. Content Type header will be added conditionally.

Following is the code for that.

@Injectable()
export class CustomRequestOptions extends BaseRequestOptions {
    constructor(private _globals: Globals) {
        super();

        this.headers.set('X-Requested-By', 'Angular 2');
        this.headers.append('virglk', "vigamage");
    }

    merge(options?: RequestOptionsArgs): RequestOptions {

        var newOptions = super.merge(options);

        let hdr = this._globals.getAuthorization();
        newOptions.headers.set("Authorization", hdr);

        if(this._globals.getRequestFrom() != "save-photo"){
            newOptions.headers.set('Content-Type', 'application/json');
        }else{
            //request coming from save photo
            console.log("request coming from save photo");
        }

        return newOptions;
    }

}

This conditional header appending is working fine. The purpose of doing that is if I add 'Content-Type', 'application/json' header to every request, file upload method in Spring controller will not accept it. (Returns http 415)

Everything seems to be fine. But I get Required request part 'file' is not present error response. Why is that? I am adding that param to the form Data.

let formData: FormData = new FormData();
formData.append('file', photoToSave);

This is the Spring Controller method for your reference.

@RequestMapping(method = RequestMethod.POST, value = "/tender/save-new/save-photo", consumes = {"multipart/form-data"})
public ResponseEntity<?> uploadPhoto(@RequestParam("file") MultipartFile file){

    if (file.isEmpty()) {
        ErrorResponse errorResponse = new ErrorResponse();
        errorResponse.setMessage("DEBUG: Attached file is empty");
        return new ResponseEntity<ErrorResponse>(errorResponse, HttpStatus.NOT_FOUND);
    }
    String returnPath = null;
    try {
        // upload stuff
    } catch (IOException e) {
        ErrorResponse errorResponse = new ErrorResponse();
        errorResponse.setMessage(e.getMessage());
        return new ResponseEntity<ErrorResponse> (errorResponse, HttpStatus.INTERNAL_SERVER_ERROR);
    }

    return new ResponseEntity<String>(returnPath, HttpStatus.OK);
}

EDIT - Adding the payload of the request captured by the browser

enter image description here

As you can see, the param "file" is available there.

5
  • Have exactly the same issue. Please let me know, if u solved the problem Commented May 29, 2017 at 13:56
  • Hi, just figured it out. The problem was with getting the input object from the DOM. There was no problem with server code. When you console log the input file, wt it prints? just let me know
    – vigamage
    Commented May 29, 2017 at 15:15
  • 2
    Thankss broo! Your hint worked! I passed an Array of files to the server instead of an single array!! Thanks!! Commented May 30, 2017 at 13:38
  • happy to hear that :)
    – vigamage
    Commented May 30, 2017 at 16:33
  • could you post the solution that worked please ? I'm struggling
    – Sandwell
    Commented Sep 12, 2019 at 12:59

4 Answers 4

0

Try to add

headers: {
            'Content-Type': 'multipart/form-data'
        },

to your

.post(this._endpointUrl + "save-photo", formData)
0
0

Change formData.append('file', photoToSave); to
             formData.append('file', this.photoToSave, this.photoToSave.name);
and also add headers specifying the type of data you are passing to API, in your case it will be
'Content-Type': 'multipart/form-data'. Post the output here if it fails even after changing this.

0

Is there a chance that you're using zuul in a secondary app that is forwarding the request? I saw this with an update where the headers were stripped while forwarding a multi-part upload. I have a gatekeeper app which forwards requests using zuul to the actual service via a looking from eureka. I fixed it by modifying the url like this:

http://myserver.com/service/upload

to

http://myserver.com/zuul/service/upload

Suddenly the 'file' part of the upload header was no longer stripped away and discarded.

The cause, I suspect was a re-try mechanism which cached requests. On failure, it would re-submit the requests, but somehow for file uploads, it wasn't working properly.

0
  1. To upload a file to the server, send your file inside a FormData and set content type as multipart/form-data.

export const uploadFile = (url, file, onUploadProgress) => {
    let formData = new FormData();

    formData.append("file", file);

    return axios.post(url, formData, {
        headers: {
            'Content-Type': 'multipart/form-data;charset=UTF-8',
            // other headers


        },
        onUploadProgress,
    })
};

  1. To handle file object, be careful with consumes attribute and @RequestPart annotation here.
@PostMapping(value = "/your-upload-path", consumes = "multipart/form-data")
public ResponseEntity<Object> uploadFile(@RequestPart("file") @Valid @NotNull @NotBlank MultipartFile file) {
    // .. your service call or logic here
}

Not the answer you're looking for? Browse other questions tagged or ask your own question.