Retrofit提供了更方便的上傳(表單): Retrofit2 使用@Multipart上傳文件
但是,有些特殊的需求,服務端以json格式接收圖片信息,Android端需要將圖片轉換成base64,上傳到服務端。
1、圖片需要轉換成base64:
1、使用 android.util.Base64;
2、編碼格式設置爲:NO_WRAP(消除換行符);
- DEFAULT 這個參數是默認,使用默認的方法來加密
- CRLF 這個參數看起來比較眼熟,它就是Win風格的換行符,意思就是使用CRLF 這一對作爲一行的結尾而不是Unix風格的LF
- NO_PADDING 這個參數是略去加密字符串最後的”=”
- NO_WRAP 這個參數意思是略去所有的換行符(設置後CRLF就沒用了)
- URL_SAFE 這個參數意思是加密時不使用對URL和文件名有特殊意義的字符來作爲加密字符,具體就是以-和 _ 取代+和/
/**
* 將圖片轉換成Base64編碼的字符串
* <p>
* https://blog.csdn.net/qq_35372900/article/details/69950867
*/
public static String imageToBase64(File path) {
InputStream is = null;
byte[] data;
String result = null;
try {
is = new FileInputStream(path);
//創建一個字符流大小的數組。
data = new byte[is.available()];
//寫入數組
is.read(data);
//用默認的編碼格式進行編碼
result = Base64.encodeToString(data, Base64.NO_WRAP);
} catch (Exception e) {
e.printStackTrace();
} finally {
if (null != is) {
try {
is.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
return result;
}
2、接口聲明:
注意,以Json格式請求:
addHeader(“Content-Type”, “application/json”);
//實體類形式
@POST(pathUrl + "/vehicle/gather")
Call<HttpBaseResult<VehicleResponse>> uploadInfo2(@Body UploadInfo uploadInfo);
//Map形式
@POST(pathUrl + "/vehicle/gather")
Call<HttpBaseResult<VehicleResponse>> uploadInfo3(@Body Map<String, String> files);
3、接口調用1(Map形式):
public static Map<String, String> getRequestMap(Context mContext, VehicleResponse response) {
Map<String, String> map = new HashMap<>();
String imageUrl = response.getImgUrl();
File file = null;
try {
file = Luban.with(mContext).load(imageUrl).get(imageUrl);
} catch (IOException e) {
e.printStackTrace();
}
String imgBase64 = imageToBase64(file);
map.put("file", imgBase64);
map.put("plateNo", response.getPlateNo());
...
map.put("gatherTime", DateUtil.Long2String(response.getGatherTime(), "yyyy-MM-dd HH:mm:ss"));
map.put("userCode", VehicleCollectSp.getUserName());
return map;
}
private void uploadInfo(VehicleResponse response) {
serviceApi.uploadInfo3(BizUtil.getRequestMap(mContext, response)).enqueue(new HttpRequestCallback<VehicleResponse>() {
@Override
public void onSuccess(VehicleResponse result) {
super.onSuccess(result);
LegoLog.d("上傳成功,result:" + result.getImgUrl());
});
}
@Override
public void onFailure(int status, String message) {
super.onFailure(status, message);
LegoLog.d("上傳失敗,message:" + message);
}
});
}
}
4、接口調用2(實體類形式):
private void uploadInfo(VehicleResponse response) {
serviceApi.uploadInfo2(BizUtil.getUploadInfo(mContext, response)).enqueue(new HttpRequestCallback<VehicleResponse>() {
@Override
public void onSuccess(VehicleResponse result) {
super.onSuccess(result);
LegoLog.d("上傳成功,result:" + result.getImgUrl());
});
}
@Override
public void onFailure(int status, String message) {
super.onFailure(status, message);
LegoLog.d("上傳失敗,message:" + message);
}
});
}
public static UploadInfo getUploadInfo(Context mContext, VehicleResponse response) {
UploadInfo info = new UploadInfo();
String imageUrl = response.getImgUrl();
File file = null;
try {
file = Luban.with(mContext).load(imageUrl).get(imageUrl);
} catch (IOException e) {
e.printStackTrace();
}
String imgBase64 = imageToBase64(file);
info.setFile(imgBase64);
info.setPlateNo(response.getPlateNo());
...
return info;
}