JQuick-Curl 文件上传下载实战:单文件、多文件、带参上传,第三方接口调用一次讲透
项目地址:https://github.com/dromara/jquick-curl
Maven坐标
<dependency>
<groupId>io.github.paohaijiao</groupId>
<artifactId>jquick-curl</artifactId>
<version>2.1.0</version>
</dependency>
前言
在真实业务开发里,文件相关接口几乎绕不开:上传发票、上传对账单、上传身份证明、下载报表、下载回执、批量导出结果文件。很多开发者在用 java http 客户端 处理这类接口时,最头疼的不是能不能调,而是 multipart、文件路径、表单字段、响应保存这些细节写起来很繁琐。
JQuick-Curl 在这类场景的优势非常明显,因为文件上传下载本来就是 curl 的强项。只要 curl 命令能表达,JQuick-Curl 就能以很接近原始命令的方式放进 Java 项目。对做第三方接口调用、curl 转 java 的开发者来说,这能明显减少样板代码和调试成本。
这一篇我们就专门讲文件相关实战:单文件上传、多文件上传、带表单参数上传,以及下载文件的两种常用方式。
正文
JQuick-Curl 里文件上传的核心写法
文件上传主要依赖 curl 的 -F 或 --form。这类命令在 JQuick-Curl 里也保持一致。
-F 'file=@/path/to/file':上传单个文件- 多个
-F:上传多个文件 - 文件字段和普通字段混写:上传文件并同时提交表单参数
这个设计很符合真实开发习惯,因为大多数上传接口的原始文档就是这么描述的。
单文件上传
最常见场景就是上传一个文件给第三方平台,比如发票 PDF、图片、Excel。
实战代码块
import com.github.paohaijiao.anno.JCurlCommand;
import com.github.paohaijiao.domain.req.JQuickCurlReq;
import com.github.paohaijiao.executor.JCurlInvoker;
public interface FileUploadApi {
@JCurlCommand("curl -X POST https://api.example.com/upload -F 'file=@D:\\test\\report.pdf'")
String upload(JQuickCurlReq request);
static void main(String[] args) throws Exception {
FileUploadApi api = JCurlInvoker.createProxy(FileUploadApi.class);
String result = api.upload(new JQuickCurlReq());
System.out.println(result);
}
}
这里最关键的是路径写法。Windows 下要注意 Java 字符串和文件路径的转义问题。
多文件上传
很多接口支持一次上传多个附件,比如多个对账文件、多个凭证图片。JQuick-Curl 直接复用多个 -F 参数即可。
public interface MultiFileUploadApi {
@JCurlCommand("curl -X POST https://api.example.com/upload-multiple -F 'files=@D:\\test\\a.xlsx' -F 'files=@D:\\test\\b.xlsx'")
String uploadMultiple(JQuickCurlReq request);
}
这类场景如果用普通 Java HTTP 模板代码来写,通常要手动处理 multipart body;而在 JQuick-Curl 里,直接沿用 curl 语法即可。
带参数的文件上传
业务里更常见的是“文件 + 业务字段”一起提交。比如上传文件时顺带传用户编号、业务单号、导入模式等。
public interface UploadWithParamsApi {
@JCurlCommand("curl -X POST https://api.example.com/import -F 'userId=1001' -F 'bizType=invoice' -F 'file=@D:\\test\\invoice.xlsx'")
String uploadWithParams(JQuickCurlReq request);
}
这正是第三方接口调用里很高频的一种格式。使用 JQuick-Curl 的好处是,文档给你的 curl 基本不用重新翻译。
文件下载:直接写文件
下载文件在 JQuick-Curl 中同样非常直接。你可以通过 --output 或 -o 指定文件保存路径。
public interface FileDownloadApi {
@JCurlCommand("curl -X GET https://api.example.com/files/report.xlsx --output 'D://test//report.xlsx'")
byte[] downloadToFile(JQuickCurlReq request);
}
虽然方法声明为 byte[],但命令里带了 --output 后,执行器会把响应字节写入命令指定文件。
文件下载:返回字节数组后自行保存
如果你希望业务层自己决定保存位置、命名规则、存储策略,也可以不写 --output,而是直接拿 byte[]。
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.nio.file.StandardOpenOption;
public interface ByteDownloadApi {
@JCurlCommand("curl -X GET https://api.example.com/files/report.xlsx")
byte[] download(JQuickCurlReq request);
static void main(String[] args) throws Exception {
ByteDownloadApi api = JCurlInvoker.createProxy(ByteDownloadApi.class);
byte[] bytes = api.download(new JQuickCurlReq());
Path path = Paths.get("D://test/report.xlsx");
Files.write(path, bytes, StandardOpenOption.CREATE);
}
}
这种方式更适合文件名由业务动态生成,或者下载后还要做二次处理的场景。
为什么说它特别适合文件类第三方接口调用
因为这类接口在 curl 文档里通常已经表达得很完整了,而传统 java http 客户端 写法会让上传下载逻辑迅速变复杂。JQuick-Curl 把“文档里的 curl”直接转成“项目里的执行命令”,能明显降低实现门槛。
尤其当你在对接支付、物流、票据、财务、报表平台时,文件接口往往是最难调的那一类。此时命令与代码保持一致,调试效率会高很多。
注意点 / 踩坑提示
1. Windows 路径要注意转义
在 Java 字符串里,D:\test\file.txt 这种路径要注意反斜杠;如果直接写在 curl 命令中,也要保持路径格式清晰。
2. --output 和 byte[] 语义不要混淆
带 --output 时,框架会写文件;不带 --output 时,更推荐由业务代码自己保存字节数组。
3. 上传字段名必须和服务端约定一致
比如服务端要求 file、files、attachment,这些名字不能随便改。
4. 文件不存在时要先排查本地路径
很多“上传失败”根本不是 HTTP 问题,而是本地路径写错、文件不存在或权限不足。
总结
文件上传下载是 JQuick-Curl 最实用的一类能力。它让原本在 java http 客户端 中容易变复杂的 multipart 和下载逻辑,重新回到 curl 擅长的命令表达方式上。对开发者来说,越是复杂、越是难调的第三方接口调用,这种“命令即实现”的方式价值越大。
如果你的项目中有大量上传导入、附件同步、报表下载、回执拉取一类场景,JQuick-Curl 会比手写模板代码更省力,也更贴近真实联调方式。
下一篇预告
下一篇我们把支持的 HTTP 方法真正串起来讲清楚:GET、POST、PUT、PATCH、DELETE、HEAD、OPTIONS、TRACE 在 JQuick-Curl 里分别适合什么场景,怎样写才更稳。