React + Spring Boot上传文件和表单数据

cum*_*lat 5 java rest reactjs spring-boot axios

我有一个像我的表单(前端)一样的情况,我可以填写个人数据(姓名、地址、出生日期),然后我可以附加多个图像。

在我的春季启动控制器中:

@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);
}
Run Code Online (Sandbox Code Playgroud)

我的模型包装:

public class CustOrderRequest {
    private String receiverName;
    private String receiverPhone;
    private String itemDescription;
    private MultipartFile[] fileAttachment;
}
//setter & getter 
Run Code Online (Sandbox Code Playgroud)

前端(React)代码:

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 
    });
Run Code Online (Sandbox Code Playgroud)

通过上面的例子,我总是遇到错误。例如:java.io.IOException:流已关闭且附件长度为零/附件大小为零(从 MultipartFile 数组或 MultipartFile 列表进行切换)。请对这种情况进行一些说明,因为很多教程仅用于上传附件部分,不包括用户填写的表单数据。先谢谢了。

教程参考:SO MK

更新了前端代码:

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

axios.post(urlApi, fd)
    .then(r => {
    // success request 
    });
Run Code Online (Sandbox Code Playgroud)

使用 formdata 更改了前端代码,然后在后端出现错误:

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]]
Run Code Online (Sandbox Code Playgroud)

Meh*_*ami 3

已编辑

第一个异常解决方案

您正在multipart/form-data服务器端进行消费,因此您必须将数据作为formData.

使用 const formData = new FormData(form);而不是 JSON.stringify


第二个异常解决方案

你的第二个例外是绑定错误,你试图绑定StringMultipart,这是因为这一行

fd.append("fileAttachment", values.fileAttachment);
Run Code Online (Sandbox Code Playgroud)

onChange1-您可以在文件表单中设置一个,例如onFileChangeHandler

<input type="file" className="form-control" name="file" onChange={this.onFileChangeHandler}/>
Run Code Online (Sandbox Code Playgroud)

2-设置上传的文件formData 并发送(如下面的代码)

的正文onChange可以如下

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 
        });
Run Code Online (Sandbox Code Playgroud)

以下链接可能对您的情况有用:

使用 React Js (Axios) 和 Spring REST 上传文件