0

I need to upload a photo to the server which has been written using Spring Boot. For the front end which sends the request I use Angular2.

This is my API which accepts the HTTP request. It works fine. (I tested it using Postman)

@RequestMapping(method = RequestMethod.POST, value = "/tender/save-new/save-photo")
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);
}

I am not sure how should I write the code in Angular2 to call the server. Following is what I have come up with.

 savePhoto(photoToSave: File) {

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

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

    return savedPath;
}

As you can see, I append the 'file' parameter to the form data before sending it. Server method accepts the RequestParam as 'file'.

But, in the server log, I get following error.

org.springframework.web.multipart.MultipartException: Current request is not a multipart request at org.springframework.web.method.annotation.RequestParamMethodArgumentResolver.handleMissingValue(RequestParamMethodArgumentResolver.java:190)

Note that I haven't declared a CommonsMultipartResolver bean since SprinBoot implicitly handles it. (I have heard this. Please correct if I am wrong.)

I think that the error comes up because of a missing value in the request. What Spring is saying by handleMissingValue? What am I missing?

2 Answers 2

1

you need to specify that your controller is expecting multipart

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

Also to solve the CORS problem you need to add the methods you are planning to use in your cors mapping, try something like this

 @Configuration
 public class WebMvcConfiguration {

@Bean
public WebMvcConfigurer corsConfigurer() {
    return new WebMvcConfigurerAdapter() {
        @Override
        public void addCorsMappings(CorsRegistry registry) {
            registry.addMapping("/**").allowedMethods("GET", "POST", "PUT", "DELETE", "HEAD");
        }
    };
}
}
Sign up to request clarification or add additional context in comments.

10 Comments

but according to following answer, Angular2 final supports file upload without xhr stackoverflow.com/a/39862337/3892439
hmm that is interesting, did not know it was supported, did you the second part of the solution where you put consumes = {"multipart/form-data"} in your request mapping?
yes. Now it gives me `` No 'Access-Control-Allow-Origin' header is present on the requested resource. Origin 'localhost:3000' is therefore not allowed access. `` . But the thing is I have put @CrossOrigin(origins = "http://localhost:3000") in my controller
ok then your issue is resolved, this error related to CORS protocol which protect your controller from being accessed from another domain, i will edit my answer to solve this issue as well.
please feel free to accept the answer if it solved your issue
|
0

i had the same problem, this is the solution i am using right now:

for the back end using spring boot:

 @RequestMapping(value="/save", method = RequestMethod.POST)
public ResponseEntity<?> saveTemp(@RequestParam("file") MultipartFile file) throws Exception{
    String nomFichier=file.getOriginalFilename();

    try {
        byte[] bytes = file.getBytes();
        File fi=new File(tempRepo+nomFichier);
        fi.getParentFile().mkdirs();
        BufferedOutputStream bufferedOutputStream = new BufferedOutputStream((new FileOutputStream(fi)));
        bufferedOutputStream.write(bytes);
        bufferedOutputStream.close();



    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        return new ResponseEntity<>(HttpStatus.BAD_REQUEST);
    }
    return new ResponseEntity<>(HttpStatus.OK);
}

for the front end using Angular2:

public save(file:any){

 const formData = new FormData();
 formData.append("file", file);

 return this._http
  .post('http://localhost:8081/save', formData)
  .catch(this._errorhandler);
}

2 Comments

Do you set the header of the particular http request to something or not?
No i dont set the header of the request, it's done automatically

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.