Java和Qt如何实现multipartfile表单的请求

1 篇文章 0 订阅

一、背景

        做项目经常需要跟其他单位/公司对接,由于成本等方面的考虑,不可能多家单位一直坐在一起开发。

        一般的解决办法是,自己的B端、C端先与自己的服务端对接,基本功能开发完成,再将自己的服务端与对方的服务端对接。

        所以就会遇到Java请求其他服务接口的问题,Get、Post发JSON数据都比较简单。最近遇到了需要发送复杂表单数据的情况,比如普通字段数据与文件一起发给对方。

二、遇到的问题

        很多做Java开发的,只知道怎么跟B端对接,但是并不清楚HTTP层到底发送的什么数据,即他不知道自己接收的什么数据,所以做Java端或者C端去请求那个接口,得猜一下数据格式。

        GET没什么好说的,主要是POST。

        POST的body中一般装载Json数据;普通表单也很常见,即body中多个参数用key1=value1&key2=value2的形式。

        如果需要发送的数据除了普通字段数据,还包含文件,尤其是二进制文件,就肯定是复杂表单了,Content-Type为“multipart/form-data”,如下图:

三、Java写法

String url = "https://api.baidu.com/xxx/xxx/xxx";
// 组装数据
MultiValueMap<String, Object> formData = new LinkedMultiValueMap<>();
formdata.add("name", getName());
...
{
    String filePath = "D:\xx\xx\xx";
    formData.add("file", new FileSystemResource(new File(filePath)));
}
// 设置Http请求头
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.MULTIPART_FORM_DATA);
// 封装请求对象
HttpEntity<MultiValueMap<String, Object>> httpEntity = new HttpEntity<>(formData, httpHeaders);
// 请求网络
RestTemplate restTemplate = new RestTemplate();
String responseString = resTemplate(url, httpEntity, String.class);

        给我最大的困扰是文件用什么对象,网上资料多是前端请求后端的Java写法,让用MultipartFile对象,添加进去一直报错。用“octet-stream”才搜索到我想要的,即需要FileSystemResource对象。

        另一处关键的地方是MediaType.MULTIPART_FORM_DATA,即指定body中的数据类型。

四、Qt写法

// 网络请求对象
QNetworkRequest request;
request.setUrl(QUrl("https://api.baidu.com/xx/xx"));
// 发送的数据
QHttpMultiPart *multiPart = new QHttpMultiPart(QHttpMultiPart::FormDataType);
{ // 普通字段
    QHttpPart httpPart;
    httpPart.setBody(xxx);
    httpPart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"xxx\";");
    multiPart->append(httpPart);
}
...
{ // 文件
    QFile *pFile = new QFile(xxx);
    pFile->open(QIODevice::ReadOnly); // 必须打开不能关闭
    pFile->setParent(multiPart); // 加了这句,pFile就不需要delete了
    //
    QHttpPart httpPart;
    httpPart.setBodyDevice(pFile);
    httpPart.setHeader(QNetworkRequest::ContentTypeHeader, QVariant("application/octet-stream"));
    httpPart.setHeader(QNetworkRequest::ContentDispositionHeader, "form-data; name=\"xx\"; filename=\"xx\";");
    multiPart->append(httpPart);
}
...
// 网络请求
QNetworkAccessManager accessManager;
QNetworkReply *reply = accessManager.post(request, multiPart);
multiPart->setParent(reply); // multiPart不需要delete了
QEventLoop eventLoop;
QObject::connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
eventLoop.exec(QEventLoop::ExcludeUserInputEvents);
// 获取返回的数据
QString responseString = QString(reply->readAll());

可以使用Spring框架提供的MultipartHttpServletRequest类来实现Java后端post请求同时上传文件和参数的功能。 首先,在Controller层中定义一个post请求的方法,方法的参数为MultipartHttpServletRequest类型: ```java @PostMapping("/upload") public String upload(MultipartHttpServletRequest request) { // 处理上传的文件和参数 return "success"; } ``` 然后,在前端页面中使用form表单提交文件和参数,设置form表单的enctype属性为"multipart/form-data",并且使用input标签的type属性为"file"来上传文件: ```html <form method="post" action="/upload" enctype="multipart/form-data"> <input type="file" name="file"> <input type="text" name="param1" value="value1"> <input type="text" name="param2" value="value2"> <button type="submit">Submit</button> </form> ``` 最后,在Java后端Controller的upload方法中,通过MultipartHttpServletRequest对象获取上传的文件和参数: ```java @PostMapping("/upload") public String upload(MultipartHttpServletRequest request) { MultipartFile file = request.getFile("file"); // 获取上传的文件 String param1 = request.getParameter("param1"); // 获取参数param1 String param2 = request.getParameter("param2"); // 获取参数param2 // 处理上传的文件和参数 return "success"; } ``` 注意,MultipartFile对象的名称需要和前端页面中input标签的name属性相对应。如果上传的是多个文件,可以使用MultipartHttpServletRequest对象的getFiles方法获取所有上传的文件。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

脱离语言

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值