使用Okhttp实现上传文件+参数请求接口form-data
作者:JMzz
在进行接口对接时,常遇到需要传递多种类型参数及文件上传的情况,解决此问题的关键在于参数传递和文件上传的正确处理,在Service层和Controller层的传参,可以通过@RequestParam标注或直接使用请求实体类,但若结合文件上传,则不应使用@RequestBody注解
Okhttp实现上传文件+参数请求接口form-data
有时候需要对接一些接口,而且接口传参不仅需要各种类型的参数,甚至还要上传文件,所以遇到挺多坑,用postman的生成代码也不好用,于是就有了这篇文章。
话不多说,我们直接上代码
首先是service层
/**
* 写注释是个好习惯
*
* @param mFile
* @param accountIndex
* @param exportType
* @param clear
* @param email
* @param dimensions
* @return
* @throws IOException
*/
public String upload(MultipartFile mFile, Integer accountIndex, String exportType,
Boolean clear, String email, String dimensions) throws IOException {
// 这里是MultipartFile转File的过程
File file = new File(Objects.requireNonNull(mFile.getOriginalFilename()));
FileUtils.copyInputStreamToFile(mFile.getInputStream(), file);
// url接口路径
String url = "http://localhost:8080/upload";
// file是要上传的文件 File() 这边我上传的是excel,其他类型可以自己改这个parse
RequestBody fileBody = RequestBody.create(MediaType.parse("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"), file);//这边是把file写进来,也有写路径的,但我这边是写file文件,parse不行的话可以直接改这个"multipart/form-data"
// 创建OkHttpClient实例,设置超时时间
OkHttpClient okHttpClient = new OkHttpClient.Builder()
.connectTimeout(60L, TimeUnit.SECONDS)
.writeTimeout(60L, TimeUnit.SECONDS)
.readTimeout(60L, TimeUnit.SECONDS)
.build();
// 不仅可以支持传文件,还可以在传文件的同时,传参数
MultipartBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM) // 设置传参为form-data格式
.addFormDataPart("account_index", String.valueOf(accountIndex))
.addFormDataPart("export_type", exportType)
.addFormDataPart("clear", String.valueOf(clear))
.addFormDataPart("email", email)
.addFormDataPart("dimensions", dimensions)
.addFormDataPart("file", file.getName(), fileBody) // 中间参数为文件名
.build();
// 构建request请求体,有需要传请求头自己加
Request request = new Request.Builder()
.url(url)
.post(requestBody)
.build();
Response response = null;
String result = "";
try {
// 发送请求
response = okHttpClient.newCall(request).execute();
result = response.body().string();
log.info(url + "发送请求结果:" + result);
if (!response.isSuccessful()) {
log.info("请求失败");
return "请求失败";
}
response.body().close();
} catch (IOException e) {
log.error(e.getMessage());
}
// 会在本地产生临时文件,用完后需要删除
if (file.exists()) {
file.delete();
}
return result;
}然后controller层的传参需要用@RequestParam或者直接一个请求的实体类
如果使用实体类,千万不要加@RequestBody,不然结合上传文件会失效,上传文件使用
@RequestPart("file") MultipartFile file进行传参
(@RequestPart("file") MultipartFile file,
@RequestParam("accountIndex") Integer accountIndex,
@RequestParam("exportType") String exportType,
@RequestParam(value = "clear", required = false) Boolean clear,
@RequestParam("email") String email,
@RequestParam(value = "dimensions", required = false) String dimensions)示例如上,或者
(@RequestPart("file") MultipartFile file, RequestVo req)请求成功,问题解决。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。
