3

Below API works using postman:

POST request that accepts from the backend

Spring boot, backend code:

import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ftp.FTPClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.CrossOrigin;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.servlet.mvc.support.RedirectAttributes;

@CrossOrigin(origins = "*", maxAge = 3600)
@RestController
@Slf4j
public class UploadFile {
    @Autowired
    private FTPClient con;

    @PostMapping("/api/auth/uploadfiles")
    public String handleFileUpload(@RequestParam("file") MultipartFile file, RedirectAttributes redirectAttributes) {

        try {
            boolean result = con.storeFile(file.getOriginalFilename(), file.getInputStream());

            redirectAttributes.addFlashAttribute("message",
                    "You successfully uploaded " + file.getOriginalFilename() + "!");
        } catch (Exception e) {
            log.error(e.getMessage(), e);
            redirectAttributes.addFlashAttribute("message",
                    "Could not upload " + file.getOriginalFilename() + "!");
        }
        return "redirect:/";
    }
}

ReactJS, frontend code: I have array of objects in the this.state.ipData.

  exportFTP = async () => {
    
      const fromdata = this.state.ipData;
      alert("Data Send to FTP server");

    axios({
      method: 'post',
      url: 'http://localhost:8080/api/auth/uploadfiles',
      data: fromdata,
      header: {
        'Accept': 'application/json ,text/plain, */*',
        'Content-Type': 'multipart/form-data',
        //'Authorization': 'Bearer '+JWTToken,
      },
    })
  }

Button to trigger the function:

<button
  style={{ marginRight: "2%", marginTop: "0.25%" }}
  type="button"
  className="btn btn-info"
  onClick={() => this.exportFTP()}
>
  Export to FTP
</button>

I need to change my frontend (ReactJS) code to as I did POST request using postman. The current JS code causes below error response:

Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.multipart.MultipartException: Current request is not a multipart request] with root cause

Note that API works when using Postman. How to fix JS code?

Ajeet Shah
  • 18,551
  • 8
  • 57
  • 87
  • I try using form data but I exactly don't know how to handle the data in my state. –  Apr 06 '21 at 16:36
  • it's holding the current state of the component, some of the array data –  Apr 06 '21 at 16:41
  • yes, I think I need that array to convert JSON files or something but I couldn't find any useful resources. –  Apr 06 '21 at 16:51
  • 1
    (5557) [{…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, {…}, …] –  Apr 06 '21 at 16:53

2 Answers2

2

Try to remove the header and send the request

    exportFTP = async () => {
    
      const fromdata = this.state.ipData;
      alert("Data Send to FTP server");

    axios({
      method: 'post',
      url: 'http://localhost:8080/api/auth/uploadfiles',
      data: fromdata
    }).then(function (res) {
      if (res.ok) {
        alert("Perfect! ");
      } else if (res.status == 401) {
        alert("Oops! ");
      }
    }, function (e) {
      alert("Error submitting form!");
    });
}
  • thanks for your attention to my question. But still, I get the same error from the backend. –  Apr 06 '21 at 16:14
2

You are sending JSON data as Blob in a multipart request. So, you need to use Blob API.

Create a function to create a blob from JSON data:

function jsonBlob(obj) {
  return new Blob([JSON.stringify(obj)], {
    type: "application/json",
  });
}

And use this function in the request:

exportFTP = async () => {
  const formData = new FormData();
  formData.append("file", jsonBlob(this.state.ipData))

  axios({
    method: "post",
    url: "http://localhost:8080/api/auth/uploadfiles",
    data: formData,

    /* You had a Typo: it is "headers" not "header".
    And, multipart/form-data header should get set automatically 
    as we used FormData. You might not need to add that manually. */
    // You may also not need Accept header; (should be set automatically).
    
    headers: { 
      Accept: "application/json ,text/plain, */*",
      "Content-Type": "multipart/form-data",
      // 'Authorization': 'Bearer '+ JWTToken,
    },
  });
};
Ajeet Shah
  • 18,551
  • 8
  • 57
  • 87
  • 1
    This is truly working is there any method to reduce the size of jsonBlob –  Apr 06 '21 at 17:25
  • Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.web.multipart.MaxUploadSizeExceededException: Maximum upload size exceeded; nested exception is java.lang.IllegalStateException: org.apache.tomcat.util.http.fileupload.impl.FileSizeLimitExceededException: The field file exceeds its maximum permitted size of 1048576 bytes.] with root cause –  Apr 06 '21 at 17:30
  • I used an apache FTP server run on my local macine. But there is no limitations add on my code. –  Apr 06 '21 at 17:31
  • 1
    thank u very much I just add spring.servlet.multipart.max-file-size=10MB spring.servlet.multipart.max-request-size=10MB to application.properties and its now works –  Apr 06 '21 at 17:44
  • And yes, you are correct: [Max limit of MultipartFile in Spring Boot](https://stackoverflow.com/a/44332602/2873538) – Ajeet Shah Apr 06 '21 at 17:56