如何在单个请求中同时POST提交PDF文件与FormGroup?(Angular+Spring后端)
同请求提交PDF文件与表单数据的实现
常见踩坑场景
尝试在同一请求中同时传递PDF文件对象与Angular FormGroup表单数据时,先后试过两种实现都未成功:
- 方案1:PDF文件封装为FormData传递,FormGroup直接原样提交
- 方案2:将PDF与FormGroup数据一同放入FormData中传递
始终无法完成数据联通,也不清楚Spring REST接口需要搭配哪些注解才能正确接收两类数据。
存在问题的初始代码
前端TS代码
onSubmit() { const formData = new FormData(); formData.append('pdfFile', this.myfile); this.form.removeControl('pdfFile'); formData.append('invoice', this.form.value) this.http.post("http://localhost:8080/zugferd/matform", formData) .subscribe(res => { console.log(res); }); }
后端Spring Controller代码
@CrossOrigin(origins = "http://localhost:4200") @PostMapping(value = "/matform") public void both(@RequestPart("pdfFile") MultipartFile pdfFile, @RequestPart("invoice") MyInvoice invoice, HttpServletResponse response) throws IOException { System.out.println(invoice.getSender().getStreet()); System.out.println(pdfFile); }
跑不通的核心原因
直接将FormGroup的value对象append到FormData时,浏览器会自动将普通JS对象序列化为[object Object]格式的字符串,后端无法将该字符串反序列化为对应的MyInvoice实体类,自然接收失败。
已验证可行的解决方案
修改后的前端TS代码
将FormGroup的JSON序列转为带application/json类型的Blob对象,再append到FormData中,保证后端可以正确识别内容类型完成反序列化:
onSubmit() { const formData = new FormData(); formData.append('pdfFile', this.myfile); this.form.removeControl('pdfFile'); const json = JSON.stringify(this.form.value); const blob = new Blob([json], {type: 'application/json'}) formData.append('form', blob) this.http.post("http://localhost:8080/zugferd/matform", formData) .subscribe(res => { // 自定义响应处理逻辑 }); }
配套后端代码调整
后端接收的@RequestPart注解中的字段名需要和前端append的字段名完全一致,同时显式声明接口接收的内容类型为multipart/form-data,Spring会自动解析对应分段中的JSON内容并绑定到实体类:
@CrossOrigin(origins = "http://localhost:4200") @PostMapping(value = "/matform", consumes = MediaType.MULTIPART_FORM_DATA_VALUE) public void both(@RequestPart("pdfFile") MultipartFile pdfFile, @RequestPart("form") MyInvoice invoice, HttpServletResponse response) throws IOException { System.out.println(invoice.getSender().getStreet()); System.out.println(pdfFile); }
内容的提问来源于stack exchange,提问作者Nazurii
相关产品推荐
相关产品推荐

