Okhttpをhttpclientとして使用します。私はそれが良いAPIだと思いますが、ドキュメントはそれほど詳細ではありません。
それを使用してファイルのアップロードでhttp投稿リクエストを行う方法は?
public Multipart createMultiPart(File file){
Part part = (Part) new Part.Builder().contentType("").body(new File("1.png")).build();
//how to set part name?
Multipart m = new Multipart.Builder().addPart(part).build();
return m;
}
public String postWithFiles(String url,Multipart m) throws IOException{
ByteArrayOutputStream out = new ByteArrayOutputStream();
m.writeBodyTo(out)
;
Request.Body body = Request.Body.create(MediaType.parse("application/x-www-form-urlencoded"),
out.toByteArray());
Request req = new Request.Builder().url(url).post(body).build();
return client.newCall(req).execute().body().string();
}
私の質問は:
注:この回答は、okhttp 1.x/2.x用です。 3.xについては、 this other answer を参照してください。
mimecraft のクラスMultipart
は、HTTP本体全体をカプセル化し、次のように通常のフィールドを処理できます。
Multipart m = new Multipart.Builder()
.type(Multipart.Type.FORM)
.addPart(new Part.Builder()
.body("value")
.contentDisposition("form-data; name=\"non_file_field\"")
.build())
.addPart(new Part.Builder()
.contentType("text/csv")
.body(aFile)
.contentDisposition("form-data; name=\"file_field\"; filename=\"file1\"")
.build())
.build();
multipart/form-dataエンコーディングの例 を見て、どのようにパーツを構築する必要があるのかを理解してください。
Multipart
オブジェクトを取得したら、あとは、右側のContent-Type
ヘッダーおよびリクエストにボディバイトを渡します。
あなたは私が経験していないOkHttp APIのv2.0で作業しているように見えるので、これは単なる推測コードです:
// You'll probably need to change the MediaType to use the Content-Type
// from the multipart object
Request.Body body = Request.Body.create(
MediaType.parse(m.getHeaders().get("Content-Type")),
out.toByteArray());
OkHttp 1.5.4の場合、 サンプルスニペット から適応された、私が使用しているコードを削除します。
OkHttpClient client = new OkHttpClient();
OutputStream out = null;
try {
URL url = new URL("http://www.example.com");
HttpURLConnection connection = client.open(url);
for (Map.Entry<String, String> entry : multipart.getHeaders().entrySet()) {
connection.addRequestProperty(entry.getKey(), entry.getValue());
}
connection.setRequestMethod("POST");
// Write the request.
out = connection.getOutputStream();
multipart.writeBodyTo(out);
out.close();
// Read the response.
if (connection.getResponseCode() != HttpURLConnection.HTTP_OK) {
throw new IOException("Unexpected HTTP response: "
+ connection.getResponseCode() + " " + connection.getResponseMessage());
}
} finally {
// Clean up.
try {
if (out != null) out.close();
} catch (Exception e) {
}
}
Okhttpを使用してファイルと任意のフィールドをアップロードする基本的な関数を次に示します(通常のHTMLフォーム送信を文字通りシミュレートします)
ファイルに一致するようにMIMEタイプを変更します(ここでは.csvを想定しています)。または、異なるファイルタイプをアップロードする場合は、関数のパラメーターにします。
public static Boolean uploadFile(String serverURL, File file) {
try {
RequestBody requestBody = new MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("file", file.getName(),
RequestBody.create(MediaType.parse("text/csv"), file))
.addFormDataPart("some-field", "some-value")
.build();
Request request = new Request.Builder()
.url(serverURL)
.post(requestBody)
.build();
client.newCall(request).enqueue(new Callback() {
@Override
public void onFailure(final Call call, final IOException e) {
// Handle the error
}
@Override
public void onResponse(final Call call, final Response response) throws IOException {
if (!response.isSuccessful()) {
// Handle the error
}
// Upload successful
}
});
return true;
} catch (Exception ex) {
// Handle the error
}
return false;
}
注:非同期呼び出しであるため、ブール値の戻り値の型はnotはアップロードが成功したことを示しますが、リクエストは送信されただけですokhttpキュー。
OkHttp 3.2.0で機能する回答を次に示します。
public void upload(String url, File file) throws IOException {
OkHttpClient client = new OkHttpClient();
RequestBody formBody = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("file", file.getName(),
RequestBody.create(MediaType.parse("text/plain"), file))
.addFormDataPart("other_field", "other_field_value")
.build();
Request request = new Request.Builder().url(url).post(formBody).build();
Response response = client.newCall(request).execute();
}
OkHttpClient client = new OkHttpClient.Builder().connectTimeout(10, TimeUnit.SECONDS).writeTimeout(180, TimeUnit.SECONDS).readTimeout(180, TimeUnit.SECONDS).build();
RequestBody body = new MultipartBody.Builder().setType(MultipartBody.FORM)
.addFormDataPart("File", path.getName(),RequestBody.create(MediaType.parse("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"),path))
.addFormDataPart("username", username)
.addFormDataPart("password", password)
.build();
Request request = new Request.Builder().url(url).post(body).build();
Response response = client.newCall(request).execute();
result = response.body().string();
上記のコードは、postパラメーターとしてユーザー名とパスワードを送信し、ファイルは「File」という名前でアップロードされます。
PHPサーバーはファイルを受信します
if (isset($_FILES["File"]) &&
isset($_POST['username']) &&
isset($_POST['password'])) {
//All Values found
}else{
echo 'please send the required data';
}
OkHttp3
のクールなヘルパークラスを作成しました。ここに
public class OkHttp3Helper {
public static final String TAG;
private static final okhttp3.OkHttpClient client;
static {
TAG = OkHttp3Helper.class.getSimpleName();
client = new okhttp3.OkHttpClient.Builder()
.readTimeout(7, TimeUnit.MINUTES)
.writeTimeout(7, TimeUnit.MINUTES)
.build();
}
private Context context;
public OkHttp3Helper(Context context) {
this.context = context;
}
/**
* <strong>Uses:</strong><br/>
* <p>
* {@code
* ArrayMap<String, String> formField = new ArrayMap<>();}
* <br/>
* {@code formField.put("key1", "value1");}<br/>
* {@code formField.put("key2", "value2");}<br/>
* {@code formField.put("key3", "value3");}<br/>
* <br/>
* {@code String response = helper.postToServer("http://www.example.com/", formField);}<br/>
* </p>
*
* @param url String
* @param formField Android.support.v4.util.ArrayMap
* @return response from server in String format
* @throws Exception
*/
@NonNull
public String postToServer(@NonNull String url, @Nullable ArrayMap<String, String> formField)
throws Exception {
okhttp3.Request.Builder requestBuilder = new okhttp3.Request.Builder().url(url);
if (formField != null) {
okhttp3.FormBody.Builder formBodyBuilder = new okhttp3.FormBody.Builder();
for (Map.Entry<String, String> entry : formField.entrySet()) {
formBodyBuilder.add(entry.getKey(), entry.getValue());
}
requestBuilder.post(formBodyBuilder.build());
}
okhttp3.Request request = requestBuilder.build();
okhttp3.Response response = client.newCall(request).execute();
if (!response.isSuccessful()) {
throw new IOException(response.message());
}
return response.body().string();
}
/**
* <strong>Uses:</strong><br/>
* <p>
* {@code
* ArrayMap<String, String> formField = new ArrayMap<>();}
* <br/>
* {@code formField.put("key1", "value1");}<br/>
* {@code formField.put("key2", "value2");}<br/>
* {@code formField.put("key3", "value3");}<br/>
* <br/>
* {@code
* ArrayMap<String, File> filePart = new ArrayMap<>();}
* <br/>
* {@code filePart.put("key1", new File("pathname"));}<br/>
* {@code filePart.put("key2", new File("pathname"));}<br/>
* {@code filePart.put("key3", new File("pathname"));}<br/>
* <br/>
* {@code String response = helper.postToServer("http://www.example.com/", formField, filePart);}<br/>
* </p>
*
* @param url String
* @param formField Android.support.v4.util.ArrayMap
* @param filePart Android.support.v4.util.ArrayMap
* @return response from server in String format
* @throws Exception
*/
@NonNull
public String postMultiPartToServer(@NonNull String url,
@Nullable ArrayMap<String, String> formField,
@Nullable ArrayMap<String, File> filePart)
throws Exception {
okhttp3.Request.Builder requestBuilder = new okhttp3.Request.Builder().url(url);
if (formField != null || filePart != null) {
okhttp3.MultipartBody.Builder multipartBodyBuilder = new okhttp3.MultipartBody.Builder();
multipartBodyBuilder.setType(okhttp3.MultipartBody.FORM);
if (formField != null) {
for (Map.Entry<String, String> entry : formField.entrySet()) {
multipartBodyBuilder.addFormDataPart(entry.getKey(), entry.getValue());
}
}
if (filePart != null) {
for (Map.Entry<String, File> entry : filePart.entrySet()) {
File file = entry.getValue();
multipartBodyBuilder.addFormDataPart(
entry.getKey(),
file.getName(),
okhttp3.RequestBody.create(getMediaType(file.toURI()), file)
);
}
}
requestBuilder.post(multipartBodyBuilder.build());
}
okhttp3.Request request = requestBuilder.build();
okhttp3.Response response = client.newCall(request).execute();
if (!response.isSuccessful()) {
throw new IOException(response.message());
}
return response.body().string();
}
private okhttp3.MediaType getMediaType(URI uri1) {
Uri uri = Uri.parse(uri1.toString());
String mimeType;
if (uri.getScheme().equals(ContentResolver.SCHEME_CONTENT)) {
ContentResolver cr = context.getContentResolver();
mimeType = cr.getType(uri);
} else {
String fileExtension = MimeTypeMap.getFileExtensionFromUrl(uri
.toString());
mimeType = MimeTypeMap.getSingleton().getMimeTypeFromExtension(
fileExtension.toLowerCase());
}
return okhttp3.MediaType.parse(mimeType);
}
}
ファイルのメタデータとともにGoogleドライブにファイルを簡単にアップロードするための完璧なコード。
String url = String.format("https://www.googleapis.com/upload/drive/v2/files?uploadType=multipart");
//String url = String.format("https://www.googleapis.com/upload/drive/v2/files?uploadType=resumable");
boolean status;
String metaDataFile = "{\"title\":\"" + step.getFile_name() + "\"," +
"\"description\":\"" + step.getDescription() + "\"," +
"\"parents\":[{\"id\":\"" + step.getFolderId() + "\"}]," +
"\"capabilities\":{\"canEdit\":\"" + false + "\", \"canDownload\":\" "+ false +" \" }, " +
"\"type\":\"" + step.getFile_access() + "\"" +
"}";
//get the encoded byte data for decode
byte[] file = Base64.decodeBase64(step.getFile_data());
//attaching metadata to our request object
RequestBody requestBodyMetaData = RequestBody.create(MediaType.parse("application/json"), metaDataFile);
//passing both meta data and file content for uploading
RequestBody requestBodyMultipart = new MultipartBody.Builder()
.setType(MultipartBody.FORM)
.addFormDataPart("metadata", null, requestBodyMetaData)
.addFormDataPart("file", null, RequestBody.create(MediaType.parse("application/octet-stream"), file))
.build();
Request request = new Request.Builder()
.url(url)
.addHeader("Authorization", String.format("Bearer %s", step.getAccess_token()))
.post(requestBodyMultipart)
.build();
OkHttpClient okHttpClient = new OkHttpClient();
try {
// Get response after rest call.
Response response = okHttpClient.newCall(request).execute();
status = response.code() == 200 ? true : false;
map.put(step.getOutput_variable(), response.code());