5

i have a case like in my form (front end), i can fill personal data (name, address, DOB) and then i can attach multiple image.

In my spring boot controller :

@RequestMapping(value = "/addCustOrder", method = RequestMethod.POST, consumes = {"multipart/form-data"})
    public String CustomerOrder(@ModelAttribute CustOrderRequest coReq, HttpServletRequest request) {
    System.out.println("debug ************** ");
    System.out.println("ReceiverName :: " + coReq.getReceiverName());
    System.out.println("attachmentFile :: " + coReq.getFileAttachment().length);
}

My model wrapper :

public class CustOrderRequest {
    private String receiverName;
    private String receiverPhone;
    private String itemDescription;
    private MultipartFile[] fileAttachment;
}
//setter & getter 

Front end (React) Code :

const payload = JSON.stringify({
    id: values.id,
    receiverName: values.receiverName,
    receiverPhone: values.receiverPhone,
    itemDescription: values.itemDescription,
    fileAttachment: values.fileAttachment
});

axios.post(urlApi, payload)
    .then(r => {
    // success request 
    });

With above example, i always encounter errors. like : java.io.IOException: Stream closed and zero attachment length / zero attachment size (have switch from array of MultipartFile or List of MultipartFile). please throw some light for this case, as a lot of tutorial out there only for upload the attachment part, not including the form data that user has filled. Thanks before.

tutorial reference : SO MK

Updated front end code :

let fd = new FormData();
fd.append("fileAttachment", values.fileAttachment);
fd.append("receiverName", values.receiverName);

axios.post(urlApi, fd)
    .then(r => {
    // success request 
    });

changed the front end code using formdata then got error in backend :

2020-02-07T17:36:10.231+0700 WARN Resolved [org.springframework.validation.BindException: org.springframework.validation.BeanPropertyBindingResult: 1 errors
Field error in object 'custOrderRequest' on field 'fileAttachment': rejected value [[object FileList]]; codes [typeMismatch.custOrderRequest.fileAttachment,typeMismatch.fileAttachment,typeMismatch.[Lorg.springframework.web.multipart.MultipartFile;,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [custOrderRequest.fileAttachment,fileAttachment]; arguments []; default message [fileAttachment]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'org.springframework.web.multipart.MultipartFile[]' for property 'fileAttachment'; nested exception is java.lang.IllegalStateException: Cannot convert value of type 'java.lang.String' to required type 'org.springframework.web.multipart.MultipartFile' for property 'fileAttachment[0]': no matching editors or conversion strategy found]]
cumibulat
  • 434
  • 3
  • 6
  • 22
  • Are the files huge? In what format are the files sent? Could you add .catch((err) => { console.log(err.message) }) after the .then() and tell when it says or maybe show browser's debugger network result for that post? Have you tried sending the file as binary (string) and then compile at backend? JSON.stringify the file seems weird. – btnhawk Feb 07 '20 at 10:20
  • Sorry, yes it's not proper to JSON.stringify the attachment. I have changed the code to use formdata. And it throwing another error. – cumibulat Feb 07 '20 at 10:50

5 Answers5

3

Edited

First Exception Solution

You are consuming multipart/form-data in your server-side, so you must send data as formData.

Use const formData = new FormData(form); instead of JSON.stringify


Second Exception Solution

Your second exception is for the binding error, you're trying to bind String into Multipart, it is because of this line

fd.append("fileAttachment", values.fileAttachment);

1- You can set an onChange in the form for file, like onFileChangeHandler

<input type="file" className="form-control" name="file" onChange={this.onFileChangeHandler}/>

2- Set uploaded file in formData and send it (like below code)

Body of onChange can be as follows

onFileChangeHandler = (e) => {
        e.preventDefault();
        this.setState({
            selectedFile: e.target.files[0]
        });
        const formData = new FormData();
        formData.append('file', this.state.selectedFile);
        //Append the rest data then send
        axios({
           method: 'post',
           url: 'myurl',
           data: formData,
           headers: {'Content-Type': 'multipart/form-data' }
        })
        .then(function (response) {
           //handle success
           console.log(response);
        }, 
        function(error) { 
           // handle error 
        });

below link might be useful for your case:

File Upload with React Js (Axios) and Spring REST

Community
  • 1
  • 1
2

I faced this problem because of wrong form implementation in react.

I was trying to append all the images at a time.

formData.append("images", images)

After looping over the images it solved my problem

for (let i = 0 ; i < images.length ; i++) {
    formData.append("images", images[i]);
}
0

You cant JSON stringify files. As far as I know in order to upload files through http you must post the data as form data. This link's answer shows how to post formdata in axios. Your java end is probably already configured for form data input.

Rafat Rashid
  • 191
  • 2
  • 10
  • I have updated my front end code, and now it's causing typemismatch error in backend. How am i supposed to send the attachment format from front end ? – cumibulat Feb 07 '20 at 10:49
0

if you use html+js as the frontend. when the file is not required, following maybe help:

var formData = new FormData(document.getElementById("yourFormId"));
Swell Yu
  • 50
  • 5
  • 1
    I notice that you have posted a very similar answer [here](https://stackoverflow.com/a/65969358/10871073). Please avoid posting the same answer to multiple questions. – Adrian Mole Jan 30 '21 at 15:25
0

Ohh well.. I understand

enter image description here

Into each array, exist the File property that spring boot converter in Multipart

Code from my js:

enter image description here