关于multipart/form-data不能提交嵌套JSON对象

需求:axios上传文件,同时还要提交简单的键值对和复杂嵌套的数据

contentType为multipart/form-data


import axios from 'axios'
var instance2 = axios.create({
  headers: { 'Content-Type': 'multipart/form-data' }
})    

let formData = new FormData()
for (let key in this.inp) {
    formData.append(key, this.inp[key])
  }
  axios.instance2.post('/webswmm/data/inp', formData ).then(({ data }) => {        
    console.log(data)
  })

// inp
  inp: {
    authority: 'private',
    files: []
  },

FormData模拟提交包含简单键值对和文件的Form表单时,如果是post请求,数据会以键值对形式被放在请求体中,这两个部分是没有问题的,后端springboot这样接收就可以了

@RestController
@RequestMapping("/webswmm/data")
@Api("上传数据")
public class DataController {

    @PostMapping(value = "/inp")
    public ResponseResult uploadFile(@RequestParam("authority") String authority,   @RequestParam("files") MultipartFile[] files){
        return null;
    }
}

但是,笔者的需求是inp还想包含其他的嵌套信息

      inp: {
        authority: 'private',
        projection: {
          code: '',
          name: '',
          extend: [],
          unit: '',
          proj4def: ''
        },
        files: []
      },

这样提交以后,后端接收到的projection是object,无法解析出projection的值。原因是multipart/form-data本来就只能发送文件和不嵌套的键值对,所以发送这样的inp肯定是不行的。

解决办法:

      inp: {
        authority: 'private',
        projection: '',
        files: []
      },

把需要嵌套的json数据在发送前用JSON.stringfy()方法转为json字符串,放入form表单中,就可以了




import axios from 'axios'
var instance2 = axios.create({
  headers: { 'Content-Type': 'multipart/form-data' }
})    

var curProjction = {}
curProject.code = '3857'
curProjction.name = 'WGS:84'
// ...其他属性赋值
this.inp.projection = JSON.stringify(curProjction)

let formData = new FormData()
for (let key in this.inp) {
    formData.append(key, this.inp[key])
  }
  axios.instance2.post('/webswmm/data/inp', formData ).then(({ data }) => {        
    console.log(data)
  })

// inp
  inp: {
    authority: 'private',
    files: []
  },

后端:

@RestController
@RequestMapping("/webswmm/data")
@Api("上传数据")
public class DataController {

    @PostMapping(value = "/inp")
    public ResponseResult uploadFile(@RequestParam("authority") String authority,   @RequestParam("files") MultipartFile[] files,@RequestParam("projection") String projection){
// 解析projection
        return null;
    }
}

 

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
`multipart/form-data` 是一种常用的 HTTP 请求数据格式,通常用于文件上传。在 Java 中,可以使用 `HttpURLConnection` 类来实现这种数据提交。 以下是一个从零开始实现 `multipart/form-data` 数据提交的示例: ```java import java.io.*; import java.net.HttpURLConnection; import java.net.URL; public class MultipartFormDataUploader { public static void main(String[] args) throws Exception { // 上传的文件 File file = new File("path/to/file"); // API 地址 String apiURL = "http://example.com/upload"; // 边界字符串 String boundary = Long.toHexString(System.currentTimeMillis()); // 请求头部分 HttpURLConnection connection = (HttpURLConnection) new URL(apiURL).openConnection(); connection.setRequestMethod("POST"); connection.setDoOutput(true); connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); // 请求体部分 try ( OutputStream output = connection.getOutputStream(); PrintWriter writer = new PrintWriter(new OutputStreamWriter(output, "UTF-8"), true); ) { // 文件部分 writer.append("--" + boundary).append("\r\n"); writer.append("Content-Disposition: form-data; name=\"file\"; filename=\"" + file.getName() + "\"").append("\r\n"); writer.append("Content-Type: " + URLConnection.guessContentTypeFromName(file.getName())).append("\r\n"); writer.append("\r\n"); writer.flush(); Files.copy(file.toPath(), output); output.flush(); writer.append("\r\n"); writer.flush(); // 其他参数部分 writer.append("--" + boundary).append("\r\n"); writer.append("Content-Disposition: form-data; name=\"param1\"").append("\r\n"); writer.append("\r\n"); writer.append("value1").append("\r\n"); writer.flush(); writer.append("--" + boundary).append("\r\n"); writer.append("Content-Disposition: form-data; name=\"param2\"").append("\r\n"); writer.append("\r\n"); writer.append("value2").append("\r\n"); writer.flush(); writer.append("--" + boundary + "--").append("\r\n"); writer.flush(); } // 响应部分 int responseCode = connection.getResponseCode(); if (responseCode == HttpURLConnection.HTTP_OK) { try ( BufferedReader reader = new BufferedReader(new InputStreamReader(connection.getInputStream(), "UTF-8")); ) { String line; while ((line = reader.readLine()) != null) { System.out.println(line); } } } else { System.err.println("上传失败,错误码:" + responseCode); } } } ``` 该示例中,我们首先获取需要上传的文件,然后指定 API 的地址和边界字符串。接下来,我们设置请求头部分,包括请求方法、数据类型和边界字符串等。然后,我们开始构造请求体部分,先写入文件部分,再写入其他参数部分。最后,我们关闭请求体部分,获取响应并处理结果。 需要注意的是,文件部分和其他参数部分之间必须要有一个换行符分隔开,即 `writer.append("\r\n");` 。另外,文件部分的内容需要使用 `OutputStream` 直接写入输出流中,而其他参数部分则可以使用 `writer` 向输出流中写入。 以上就是一个简单的 `multipart/form-data` 数据提交的实现。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值