Androidのサーバーにバイナリファイルをアップロードしたい。私は郵便配達人によってApiメソッドをテストします:
そして、あなたがファイルをフォームデータ(キー、値)としてアップロードできる別のオプションがあるのを見て、それは問題ありません:
すべてのチュートリアル( これ など)は、ファイルをmultipart/form-data
としてアップロードする方法を説明しています。
// create RequestBody instance from file
RequestBody requestFile =
RequestBody.create(MediaType.parse("multipart/form-data"), file);
// MultipartBody.Part is used to send also the actual file name
MultipartBody.Part body =
MultipartBody.Part.createFormData("picture", file.getName(), requestFile);
私はたくさん検索しましたが、retrofit2でバイナリとしてファイルをアップロードする方法を見つけることができませんでした。
retrofitリポジトリにどうすればよいPOSTレトロフィット2.0ベータの画像バイナリ?。私はそのソリューションを使用します:
APIサービス:
@POST("trip/{tripId}/media/photos")
Call<MediaPost> postEventPhoto(
@Path("eventId") int tripId,
@Header("Authorization") String accessToken,
@Query("direction") String direction,
@Body RequestBody photo);
発信者:
InputStream in = new FileInputStream(new File(media.getPath()));
byte[] buf;
buf = new byte[in.available()];
while (in.read(buf) != -1);
RequestBody requestBody = RequestBody
.create(MediaType.parse("application/octet-stream"), buf);
Call<MediaPost> mediaPostCall = tripApiService.postTripPhoto(
tripId,
((GlobalInfo) getApplicationContext()).getApiAccessToken(),
direction,
requestBody);
しかし、私はこのエラーを受け取りました:
Java.lang.IllegalArgumentException: @Body parameters cannot be used with form or multi-part encoding.
私のコードの何が問題になっていますか?私は何をすべきか?
何時間も検索したところ、@Multipart
アノテーションは、最後の例のコードのAPIインターフェイスに残っています!バイナリデータをサーバーに送信することを防ぐため、リポジトリの改造は問題ありませんでした。
最初の質問で何が起こったかを理解するために少し掘る必要があったので、別の解決策を追加するだけです。
私の解決策は、バイナリファイルをbyte[]
として直接取得し、RequestBody
内に配置することです。したがって、最終的にはコードは次のようになります。
interface RetrofitService {
@POST("api/v1/upload_file")
Call<Void> uploadBinaryFile(@Body RequestBody body);
}
そしてそれを呼び出すには:
public void uploadBinaryFile(File fileToUpload) {
retrofitService
.uploadBinaryFile(RequestBody.create(MediaType.parse("application/octet"),
Files.readAllBytes(fileToUpload));
}
これは基本的にOPの元の質問と同じですが、明確にするために、この回答も次の読者のために残しておきます。
同じ問題がありましたが、バイナリファイル(画像)をアップロードしたいと思いました。 APIはWordpressのものでした
この問題 の最後にあるソリューションコードに従いました。
これが私の少し変更されたコードです
@POST("wp-json/wp/v2/media/")
Call<ImagePostResult> postEventPhoto(
@Header("Authorization") String accessToken,
@Header("Content-Type") String contentType,
@Header("Content-Disposition") String contentDisposition,
@Body RequestBody photo);
こちらがリクエストです
// For BasicAuth
String authHeader = getAuthHeader();
String contentType = "application/binary";
String contentDisposition = "attachment; filename = " + fileName;
RequestBody requestBodyee = null;
try {
InputStream in = new FileInputStream(file);
byte[] buf;
buf = new byte[in.available()];
while (in.read(buf) != -1) ;
requestBodyee = RequestBody
.create(MediaType.parse("application/octet-stream"), buf);
} catch (IOException e) {
e.printStackTrace();
}
Call<ImagePostResult> imagePostResultCall = apiInterface.postEventPhoto(
authHeader,
contentType,
contentDisposition,
requestBodyee);
imagePostResultCall.enqueue(new Callback<ImagePostResult>() {
@Override
public void onResponse(Call<ImagePostResult> call, Response<ImagePostResult> response) {
// Response Success
if (response.isSuccessful()) {
// yaay
}
}
@Override
public void onFailure(Call<ImagePostResult> call, Throwable t) {
Log.d(TAG, "onFailure: " + t);
}
});
mediaType == Null my code:
private fun put(uploadUrl : String , localPath : String) {
val file = File(localPath)
val byteArray = file2Byte(localPath)!!
val responseBody = RequestBody.create(null , byteArray)
val call = HttpFactory.providerUp.up(uploadUrl , responseBody)
call.enqueue(object : Callback<ResponseBody> {
override fun onFailure(call : retrofit2.Call<ResponseBody>? , t : Throwable?) {
LogUtil.toast("Failure")
}
override fun onResponse(call : retrofit2.Call<ResponseBody>? , response : retrofit.Response<ResponseBody>?) {
if (response!!.code() == 200) {
LogUtil.toast("YES")
} else {
LogUtil.toast("NO")
}
}
})
}
@PUT
fun up2(@Url url : String ,@Body requestBody : RequestBody ) : Call<ResponseBody>
画像を送信することもできます
//Api Interface
@Part MultipartBody.Part body
//Call in activity
file = FileUtils.getFile(this, uri);
reqFile = RequestBody.create(MediaType.parse("image/*"), file);
body = MultipartBody.Part.createFormData("uploaded_file", "Img_" + "_" + rightNow.getTimeInMillis() + ".jpg", reqFile);