使用OkHttp3以Multipart/Form-Data方式上傳文件方式
今天遇到了一個(gè)上傳圖片接口,后端獲取file老是為null,仔細(xì)一看是ContentType:multipart/form-data,這中方式我用的不多,這邊記錄下。
準(zhǔn)備工作
首先,確保項(xiàng)目已經(jīng)添加了OkHttp3庫(kù)的依賴(lài):
implementation 'com.squareup.okhttp3:okhttp:4.9.0'
ContentType概述
ContentType,也稱(chēng)為媒體類(lèi)型或MIME類(lèi)型,用于描述網(wǎng)絡(luò)請(qǐng)求和響應(yīng)中的內(nèi)容類(lèi)型。
以下是一些常見(jiàn)的ContentType:
text/plain:普通文本text/html:HTML文檔application/json:JSON數(shù)據(jù)application/xml:XML數(shù)據(jù)image/jpeg:JPEG圖片image/png:PNG圖片multipart/form-data:用于文件上傳
本文主要關(guān)注multipart/form-data,因?yàn)樗ǔS糜诒韱翁峤?,特別是包含文件上傳的表單。
步驟
1.創(chuàng)建MediaType
MediaType mediaType = MediaType.parse("image/jpeg");MediaType用于描述文件類(lèi)型,這里我們上傳的是JPEG格式的圖片。
2.創(chuàng)建RequestBody
RequestBody fileBody = RequestBody.create(mediaType, photoFile);
RequestBody用于封裝待上傳的文件數(shù)據(jù)。
3.創(chuàng)建MultipartBody
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", photoFile.getName(), fileBody)
.build();MultipartBody用于構(gòu)建多部分表單請(qǐng)求,這里添加了文件部分。
4.添加請(qǐng)求頭
我也不知道他為什么要把參數(shù)放在url里面…
Request request = new Request.Builder()
.url("http://xx.xx.x.xx:xxxxx/fileUploadAndDownload/upload?detailNo=1234&noSave=0")
.addHeader("X-Token", token)
.post(requestBody)
.build();這里我們添加了自定義的請(qǐng)求頭X-Token。
5.發(fā)送請(qǐng)求
OkHttpClient client = new OkHttpClient();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) {
throw new IOException("Unexpected code " + response);
}
System.out.println(response.body().string());
}
});通過(guò)OkHttpClient發(fā)送請(qǐng)求,并處理響應(yīng)。
完整代碼
使用OkHttp3以multipart/form-data方式上傳圖片的示例代碼。
import okhttp3.*;
import java.io.File;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
public class UploadImage {
private static final String TAG = "UploadImage";
public static void main(String[] args) {
// 創(chuàng)建MediaType
MediaType mediaType = MediaType.parse("image/jpeg");
// 圖片文件路徑
File photoFile = new File("path/to/your/photo.jpg");
// 創(chuàng)建RequestBody
RequestBody fileBody = RequestBody.create(mediaType, photoFile);
// 創(chuàng)建MultipartBody
RequestBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", photoFile.getName(), fileBody)
.build();
// 獲取自定義請(qǐng)求頭
Map<String, String> headers = EasyConfig.getInstance().getHeaders();
String token = headers.get("X-Token");
Set<String> keySet = headers.keySet();
for (String key : keySet) {
Log.i(TAG, "uploadImage: " + headers.get(key));
}
// 創(chuàng)建Request
Request request = new Request.Builder()
.url("http://192.168.6.162:8888/fileUploadAndDownload/upload?detailNo=1234&noSave=0")
.addHeader("X-Token", token)
.post(requestBody)
.build();
// 創(chuàng)建OkHttpClient
OkHttpClient client = new OkHttpClient();
// 發(fā)送請(qǐng)求
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(Call call, IOException e) {
e.printStackTrace();
}
@Override
public void onResponse(Call call, Response response) throws IOException {
if (!response.isSuccessful()) {
throw new IOException("Unexpected code " + response);
}
// 處理響應(yīng)
System.out.println(response.body().string());
}
});
}
}我這邊使用的是EasyHttp庫(kù),multipart/form-data不知道怎么設(shè)置,導(dǎo)致EasyHttp上傳不了圖片。
所以才用原生的api先學(xué)習(xí),這邊也貼一下EasyHttp使用multipart/form-data上傳圖片。
// 創(chuàng)建RequestBody,指定媒體類(lèi)型和文件
RequestBody fileRequestBody = RequestBody.create(MediaType.parse("image/jpeg"), photoFile);
// 創(chuàng)建MultipartBody.Part,指定字段名和RequestBody
MultipartBody.Part filePart = MultipartBody.Part.createFormData("file", photoFile.getName(), fileRequestBody);
// 構(gòu)建MultipartBody
MultipartBody requestBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addPart(filePart)
.build();
EasyHttp.post(this)
.api(new UploadApi())
.body(requestBody)
.request(new OnUpdateListener<Void>() {
@Override
public void onUpdateProgressChange(int progress) {
Log.i(TAG, "onUpdateProgressChange: "+progress);
}
@Override
public void onUpdateSuccess(Void result) {
Log.i(TAG, "onUpdateSuccess:");
}
@Override
public void onUpdateFail(Throwable throwable) {
Log.i(TAG, "onUpdateFail:");
}
});總結(jié)
以上為個(gè)人經(jīng)驗(yàn),希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。
相關(guān)文章
關(guān)于在Java中反轉(zhuǎn)數(shù)組的4種詳細(xì)方法
這篇文章主要介紹了關(guān)于在Java中反轉(zhuǎn)數(shù)組的4種詳細(xì)方法,數(shù)組是一個(gè)固定長(zhǎng)度的存儲(chǔ)相同數(shù)據(jù)類(lèi)型的數(shù)據(jù)結(jié)構(gòu),數(shù)組中的元素被存儲(chǔ)在一段連續(xù)的內(nèi)存空間中,今天我們來(lái)學(xué)習(xí)一下如何反轉(zhuǎn)數(shù)組2023-05-05
SpringTask-Timer實(shí)現(xiàn)定時(shí)任務(wù)的詳細(xì)代碼
在項(xiàng)目中開(kāi)發(fā)定時(shí)任務(wù)應(yīng)該一種比較常見(jiàn)的需求,今天通過(guò)示例代碼給大家講解SpringTask-Timer實(shí)現(xiàn)定時(shí)任務(wù)的相關(guān)知識(shí),感興趣的朋友一起看看吧2024-06-06
java實(shí)現(xiàn)同步的幾種方式(示例詳解)
這篇文章主要介紹了java實(shí)現(xiàn)同步的幾種方式,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友一起看看吧2024-12-12
Mybatis配置useGeneratedKeys參數(shù)的方式
Mybatis的useGeneratedKeys參數(shù)用于控制是否允許JDBC支持自動(dòng)生成主鍵,并在插入數(shù)據(jù)時(shí)通過(guò)keyProperty將生成的主鍵值返回,當(dāng)數(shù)據(jù)庫(kù)不支持自增主鍵時(shí),可以使用selectKey來(lái)手動(dòng)實(shí)現(xiàn)類(lèi)似的效果2026-01-01
SpringBoot+RabbitMQ?實(shí)現(xiàn)死信隊(duì)列的示例
本文主要介紹了SpringBoot+RabbitMQ?實(shí)現(xiàn)死信隊(duì)列的示例,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06
Java判斷一個(gè)實(shí)體是不是空的簡(jiǎn)單方法
這篇文章主要給大家介紹了關(guān)于Java判斷一個(gè)實(shí)體是不是空的簡(jiǎn)單方法,實(shí)際項(xiàng)目中我們會(huì)有很多地方需要判空校驗(yàn),文中給出了詳細(xì)的示例代碼,需要的朋友可以參考下2023-07-07
如何使用IDEA的groovy腳本文件生成帶JPA注解的實(shí)體類(lèi)(圖文詳解)
這篇文章主要介紹了如何使用IDEA的groovy腳本文件生成帶JPA注解的實(shí)體類(lèi),本文通過(guò)圖文并茂實(shí)例相結(jié)合給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-07-07
idea解決springboot中的依賴(lài)版本沖突問(wèn)題
這篇文章主要介紹了idea解決springboot中的依賴(lài)版本沖突問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-05-05

