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]]
2
  • 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. Commented Feb 7, 2020 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. Commented Feb 7, 2020 at 10:50

5 Answers 5

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

Sign up to request clarification or add additional context in comments.

6 Comments

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 ?
This is a binding error, you're trying to bind string into multipart, please check upload file (check the type in the form, it must be file). It just like you are sending string instead of a file for the server
@cumibulat could you please show your view code to us ?
@cumibulat your problem is in fd.append("fileAttachment", values.fileAttachment); line
I have go through the link you shared and i could improvise from that tutorial. Thanks. Have seen that link before but not paying fully attention for the multipartfile + extras parameter.
|
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]);
}

1 Comment

My code work with the same strategy, but ..., Why is necessary the loop?
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.

1 Comment

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 ?
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"));

1 Comment

I notice that you have posted a very similar answer here. Please avoid posting the same answer to multiple questions.
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

Comments

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.