Sending file object to Spring Rest controller thro

2020-02-15 09:39发布

问题:

I am trying to upload a file on client side and send HTTP Post request to Spring Rest Controller. But when I receive the file object in Rest controller I could see it as 'null'. HTML code :

<input type="file" id="myFile" (change) = "onFileChange($event)" #fileInput>

Corresponding .ts file :

onFileChange($event) : void {
    let file:File = $event.target.files[0];
    let myReader: FileReader = new FileReader();       
    myReader.onloadend = function(e) {      
    }
    myReader.readAsText(file);
    const req = this.http.post('/abc',myReader.result, {
        headers: new HttpHeaders().set('content-type','application/pdf')
    });
    req.subscribe(
        (data) => {
            console.log(data);
        },
        (err: HttpErrorResponse) => {
            if(err.error instanceof Error) {
                //client side error
                console.log('An error occured: ',err.error.message);
            } else {
                console.log('Backend returned code', err.status, 'body was ',err.error);
            }
        }
    )
}

My Spring Rest Controller :

@RequestMapping(value="/abc", method = RequestMethod.POST, consumes = "application/pdf") 
public ResponseEntity<String> uploadFile(@RequestBody MultipartFile file) {
    System.out.println("Inside Controller");
    return new ResponseEntity<>("true", HttpStatus.CREATED);
}

Could anyone please help to find out the issue here.

回答1:

Try below code

HTML Template

<input type="file" id="myFile" (change)="onFileChange(fileInput.files)" #fileInput>

TypeScript

import { Headers, RequestOptions } from '@angular/http'; // Import header and requestOptions

//On File Select
onFileChange(files: any) {

    let file: File = files[0];

    let headers = new Headers();
    let options = new RequestOptions({ headers: headers }); // Create header

    let formData = new FormData();
    formData.append('file', file); // Append file to formdata

    const req = this.http.post('/abc', formData, options);

    req.subscribe( (data) => {

        console.log(data); // Sucess response
    }, (err: HttpErrorResponse) => {

        // Erro response
        if(err.error instanceof Error) {
          //client side error
          console.log('An error occured: ',err.error.message);
        }
        else {
          console.log('Backend returned code', err.status, 'body was ',err.error);
        }
    })
}

Spring Controller

@RequestMapping(value="/abc", method = RequestMethod.POST) 
public ResponseGenerator uploadFile(@RequestParam MultipartFile file) {

    ResponseGenerator responseGenerator = new ResponseGenerator();

    try {

        if (file != null) {
            System.out.println(file.getOriginalFilename());
        }
        return responseGenerator;
    } catch (Exception e) {
        logger.error("Error while updating user : ", e);
        return responseGenerator;
    }
}

It will be better way if you create one service and put your http method code in that service. refer this link Angular 2 template form with input type=file and spring boot



回答2:

the easiest thing to do (according to me) is to use a FormData object.

Here is how :

@viewChild() fileInput: ElementRef;

onFileChange(event) {
  const files = this.fileInput.nativeElement.files as FileList;
  const file = files.item(0);

  const formData = new FormData();
  formData.append('pdf', file, file.name);
  this.http.post('abc', formData, {
    headers: new HttpHeaders().set('content-type','application/pdf')
  }).subscribe(
    data => console.log(data),
    err => console.log(err)
  );
}

Try this and tell me what you see on Spring side.