2

I have 2 spring boot apps running one as a frontend and another as a backend service. From the frontend i make an api call to the backend service and both the parameters that i send show up as null. I think the problem is in the rest template.

UPDATE

So i have noticed if i omit the content value then it works. Since content is the content of a file that is larger than 1mb I added the following to application.yml:

spring.servlet.multipart.max-file-size: 10MB
spring.servlet.multipart.max-request-size: 10MB

Here is my code which I updated from one posted in this issue: How to POST form data with Spring RestTemplate?

But i still don't get the value in the backend controller instead both values are null.

        public void upload(byte[] content, String name) {
        String encodedString = Base64.getEncoder().encodeToString(content);
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED);

        MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
        map.add("fileName", name);
        map.add("content", encodedString);

        HttpEntity<MultiValueMap<String, String>> request = new HttpEntity<MultiValueMap<String, String>>(map, headers);

        ResponseEntity<String> response = restTemplate.postForEntity(backendUrl + "/upload", request, String.class);
        log.debug("Response from upload: " + response);
    }

And here is the controller in the backend. Both fileName and content are null:

        @CrossOrigin
    @SneakyThrows
    @ResponseBody
    @PostMapping(value = "/upload")
    public ResponseEntity<String> upload(@ModelAttribute FormModel form) {
        byte[] decodedBytes = Base64.getDecoder().decode(form.getContent());
        uploadService.upload(decodedBytes, form.getFileName());
        HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.set("Content-Type", "application/json");
        return ResponseEntity.ok().headers(responseHeaders).body("Uploaded");
    }

Can anyone please see what is wrong with this code?

Thanks in advance.

Amir
  • 172
  • 14

2 Answers2

1

I guess the problem is that you are trying to use restTemplate.postForObject but with @RequestParam and not a @RequestBody.

In @RequestParam you are expecting the data to be received in the query params /upload?fileName=&content=. But you are actually sending it in the body with the restTemplate.postForObject(backendService+ "/upload", map, String.class);.

So my suggestion is to change

public ResponseEntity<String> upload(@RequestParam(value = "fileName") String fileName, @RequestParam(value = "content") String content)

to

public ResponseEntity<String> upload(@RequestBody Map<String, String> body)

and then get fileName and fileContent from the body.

Amr Saeed
  • 177
  • 2
  • 12
  • Your response is in the right direction. I changed the method signature to @ModelAttribute FormModel form. But i am still getting null coming through for fileName and content. – Amir Feb 03 '21 at 11:13
0

Ok i could fix it by sending and receiving bytes instead of bytes encoded as string. So in the resttemplate:

    public void upload(byte[] bytes, String name) {
        HttpHeaders headers = new HttpHeaders();
        headers.setContentType(MediaType.MULTIPART_FORM_DATA);

        MultiValueMap<String, Object> map = new LinkedMultiValueMap<String, Object>();
        map.add("fileName", name);
        map.add("bytes", bytes);

        HttpEntity<MultiValueMap<String, Object>> request = new HttpEntity<MultiValueMap<String, Object>>(map, headers);
        log.debug("map values: " + map.toString());

        ResponseEntity<String> response = restTemplate.postForEntity(backendUrl + "/upload", request, String.class);
        log.debug("Response from upload: " + response);
    }

And in the controller:

public ResponseEntity<String> upload(@ModelAttribute FormModel form) {
        byte[] bytes = form.getBytes();
        uploadService.upload(bytes, form.getFileName());
        HttpHeaders responseHeaders = new HttpHeaders();
        responseHeaders.set("Content-Type", "application/json");
        return ResponseEntity.ok().headers(responseHeaders).body("Uploaded");
    }

Still it would be good to know why the previous version didn't work.

Amir
  • 172
  • 14