Java PHPでApacheサーバーにファイルをアップロードするアプリケーション。JavaコードはJakarta HttpClientライブラリバージョン4.0 beta2を使用します。
import Java.io.File;
import org.Apache.http.HttpEntity;
import org.Apache.http.HttpResponse;
import org.Apache.http.HttpVersion;
import org.Apache.http.client.HttpClient;
import org.Apache.http.client.methods.HttpPost;
import org.Apache.http.entity.FileEntity;
import org.Apache.http.impl.client.DefaultHttpClient;
import org.Apache.http.params.CoreProtocolPNames;
import org.Apache.http.util.EntityUtils;
public class PostFile {
public static void main(String[] args) throws Exception {
HttpClient httpclient = new DefaultHttpClient();
httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
HttpPost httppost = new HttpPost("http://localhost:9002/upload.php");
File file = new File("c:/TRASH/zaba_1.jpg");
FileEntity reqEntity = new FileEntity(file, "binary/octet-stream");
httppost.setEntity(reqEntity);
reqEntity.setContentType("binary/octet-stream");
System.out.println("executing request " + httppost.getRequestLine());
HttpResponse response = httpclient.execute(httppost);
HttpEntity resEntity = response.getEntity();
System.out.println(response.getStatusLine());
if (resEntity != null) {
System.out.println(EntityUtils.toString(resEntity));
}
if (resEntity != null) {
resEntity.consumeContent();
}
httpclient.getConnectionManager().shutdown();
}
}
PHPファイルupload.php
は非常に簡単です:
<?php
if (is_uploaded_file($_FILES['userfile']['tmp_name'])) {
echo "File ". $_FILES['userfile']['name'] ." uploaded successfully.\n";
move_uploaded_file ($_FILES['userfile'] ['tmp_name'], $_FILES['userfile'] ['name']);
} else {
echo "Possible file upload attack: ";
echo "filename '". $_FILES['userfile']['tmp_name'] . "'.";
print_r($_FILES);
}
?>
応答を読むと、次の結果が得られます。
executing request POST http://localhost:9002/upload.php HTTP/1.1
HTTP/1.1 200 OK ファイルアップロード攻撃の可能性:ファイル名 ''。 Array ( )
リクエストは成功したので、サーバーと通信できましたが、PHPはファイルに気付きませんでした-メソッドis_uploaded_file
はfalse
を返し、$_FILES
変数は空です。 HTTPの応答と要求を追跡しましたが、問題はありません。
リクエスト:
POST /upload.php HTTP/1.1 Content-Length:13091 Content-Type:binary/octet-stream Host:localhost:9002 接続:キープアライブ ユーザーエージェント:Apache-HttpClient/4.0-beta2(Java 1.5) 期待:100-Continue ˙Ř˙ ŕ.....残りのバイナリファイル...
および応答:
HTTP/1.1 100 Continue HTTP/1.1 200 OK Date:Wed、01 Jul 2009 06:51:57 GMT Server: Apache/2.2.8(Win32)DAV/2 mod_ssl/2.2.8 OpenSSL/0.9.8g mod_autoindex_color PHP/5.2.5 mod_jk/1.2.26 X-Powered-By:PHP/5.2.5 Content-Length:51 Keep-Alive:timeout = 5、max = 100 Connection:Keep-Alive Content-Type:text/html ファイルアップロード攻撃の可能性:ファイル名 '' .Array ( )
これは、xamppを使用するローカルWindows XPとリモートLinuxサーバーの両方でテストしていました。また、以前のバージョンのHttpClient(バージョン3.1)を使用しようとしましたが、結果はさらに不明確で、is_uploaded_file
はfalse
を返しましたが、$_FILES
配列には適切なデータが格納されていました。
わかりました、Java私が使用したコードは間違っていました、ここに正しいJavaクラス:
import Java.io.File;
import org.Apache.http.HttpEntity;
import org.Apache.http.HttpResponse;
import org.Apache.http.HttpVersion;
import org.Apache.http.client.HttpClient;
import org.Apache.http.client.methods.HttpPost;
import org.Apache.http.entity.mime.MultipartEntity;
import org.Apache.http.entity.mime.content.ContentBody;
import org.Apache.http.entity.mime.content.FileBody;
import org.Apache.http.impl.client.DefaultHttpClient;
import org.Apache.http.params.CoreProtocolPNames;
import org.Apache.http.util.EntityUtils;
public class PostFile {
public static void main(String[] args) throws Exception {
HttpClient httpclient = new DefaultHttpClient();
httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);
HttpPost httppost = new HttpPost("http://localhost:9001/upload.php");
File file = new File("c:/TRASH/zaba_1.jpg");
MultipartEntity mpEntity = new MultipartEntity();
ContentBody cbFile = new FileBody(file, "image/jpeg");
mpEntity.addPart("userfile", cbFile);
httppost.setEntity(mpEntity);
System.out.println("executing request " + httppost.getRequestLine());
HttpResponse response = httpclient.execute(httppost);
HttpEntity resEntity = response.getEntity();
System.out.println(response.getStatusLine());
if (resEntity != null) {
System.out.println(EntityUtils.toString(resEntity));
}
if (resEntity != null) {
resEntity.consumeContent();
}
httpclient.getConnectionManager().shutdown();
}
}
multipartEntityを使用することに注意してください。
MultipartEntity
...を使用しようとしている人向けの更新.
org.Apache.http.entity.mime.MultipartEntity
は4.3.1で廃止されました。
MultipartEntityBuilder
を使用して、HttpEntity
オブジェクトを作成できます。
File file = new File();
HttpEntity httpEntity = MultipartEntityBuilder.create()
.addBinaryBody("file", file, ContentType.create("image/jpeg"), file.getName())
.build();
Mavenユーザーの場合、このクラスは次の依存関係で利用できます(fervisaの回答とほぼ同じですが、それ以降のバージョンでも同様です)。
<dependency>
<groupId>org.Apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.3.1</version>
</dependency>
同じ問題にぶつかり、httpclient 4.xがPHPバックエンドで動作するために必要なファイル名です。httpclient3.xには当てはまりませんでした。
したがって、私の解決策は、FileBodyコンストラクターに名前パラメーターを追加することです。 ContentBody cbFile = new FileBody(file、 "image/jpeg"、 "FILE_NAME");
それが役に立てば幸い。
以下は元のコードのコピーです。
/*
* ====================================================================
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.Apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
* ====================================================================
*
* This software consists of voluntary contributions made by many
* individuals on behalf of the Apache Software Foundation. For more
* information on the Apache Software Foundation, please see
* <http://www.Apache.org/>.
*
*/
package org.Apache.http.examples.entity.mime;
import Java.io.File;
import org.Apache.http.HttpEntity;
import org.Apache.http.client.methods.CloseableHttpResponse;
import org.Apache.http.client.methods.HttpPost;
import org.Apache.http.entity.ContentType;
import org.Apache.http.entity.mime.MultipartEntityBuilder;
import org.Apache.http.entity.mime.content.FileBody;
import org.Apache.http.entity.mime.content.StringBody;
import org.Apache.http.impl.client.CloseableHttpClient;
import org.Apache.http.impl.client.HttpClients;
import org.Apache.http.util.EntityUtils;
/**
* Example how to use multipart/form encoded POST request.
*/
public class ClientMultipartFormPost {
public static void main(String[] args) throws Exception {
if (args.length != 1) {
System.out.println("File path not given");
System.exit(1);
}
CloseableHttpClient httpclient = HttpClients.createDefault();
try {
HttpPost httppost = new HttpPost("http://localhost:8080" +
"/servlets-examples/servlet/RequestInfoExample");
FileBody bin = new FileBody(new File(args[0]));
StringBody comment = new StringBody("A binary file of some kind", ContentType.TEXT_PLAIN);
HttpEntity reqEntity = MultipartEntityBuilder.create()
.addPart("bin", bin)
.addPart("comment", comment)
.build();
httppost.setEntity(reqEntity);
System.out.println("executing request " + httppost.getRequestLine());
CloseableHttpResponse response = httpclient.execute(httppost);
try {
System.out.println("----------------------------------------");
System.out.println(response.getStatusLine());
HttpEntity resEntity = response.getEntity();
if (resEntity != null) {
System.out.println("Response content length: " + resEntity.getContentLength());
}
EntityUtils.consume(resEntity);
} finally {
response.close();
}
} finally {
httpclient.close();
}
}
}
私はパーティーに遅れていることを知っていましたが、これに対処する正しい方法は次のとおりです、キーはInputStreamBody
の代わりにFileBody
を使用してマルチパートファイルをアップロードすることです.
try {
HttpClient httpclient = new DefaultHttpClient();
HttpPost postRequest = new HttpPost("https://someserver.com/api/path/");
postRequest.addHeader("Authorization",authHeader);
//don't set the content type here
//postRequest.addHeader("Content-Type","multipart/form-data");
MultipartEntity reqEntity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
File file = new File(filePath);
FileInputStream fileInputStream = new FileInputStream(file);
reqEntity.addPart("parm-name", new InputStreamBody(fileInputStream,"image/jpeg","file_name.jpg"));
postRequest.setEntity(reqEntity);
HttpResponse response = httpclient.execute(postRequest);
}catch(Exception e) {
Log.e("URISyntaxException", e.toString());
}
ああ、あなたはただ名前パラメータを追加する必要があります
FileBody constructor. ContentBody cbFile = new FileBody(file, "image/jpeg", "FILE_NAME");
それが役に立てば幸い。
受け入れられた答え(org.Apache.http.entity.mime.MultipartEntityを必要とする)の実装に苦労している人のために、org.Apache.httpcomponents 4.2。*を使用している可能性があります。この場合、明示的にインストールする必要がありますhttpmime依存関係、私の場合:
<dependency>
<groupId>org.Apache.httpcomponents</groupId>
<artifactId>httpmime</artifactId>
<version>4.2.5</version>
</dependency>
Apache httpライブラリを使用して、ポストで画像を送信するための私の実用的なソリューションがあります(ここで非常に重要なのは境界の追加です。これは私の接続では機能しません):
ByteArrayOutputStream baos = new ByteArrayOutputStream();
bitmap.compress(Bitmap.CompressFormat.PNG, 100, baos);
byte[] imageBytes = baos.toByteArray();
HttpClient httpclient = new DefaultHttpClient();
HttpPost httpPost = new HttpPost(StaticData.AMBAJE_SERVER_URL + StaticData.AMBAJE_ADD_AMBAJ_TO_GROUP);
String boundary = "-------------" + System.currentTimeMillis();
httpPost.setHeader("Content-type", "multipart/form-data; boundary="+boundary);
ByteArrayBody bab = new ByteArrayBody(imageBytes, "pic.png");
StringBody sbOwner = new StringBody(StaticData.loggedUserId, ContentType.TEXT_PLAIN);
StringBody sbGroup = new StringBody("group", ContentType.TEXT_PLAIN);
HttpEntity entity = MultipartEntityBuilder.create()
.setMode(HttpMultipartMode.BROWSER_COMPATIBLE)
.setBoundary(boundary)
.addPart("group", sbGroup)
.addPart("owner", sbOwner)
.addPart("image", bab)
.build();
httpPost.setEntity(entity);
try {
HttpResponse response = httpclient.execute(httpPost);
...then reading response
ローカルWAMPでこれをテストしている場合、ファイルのアップロード用に一時フォルダーをセットアップする必要があります。 PHP.iniファイルでこれを行うことができます。
upload_tmp_dir = "c:\mypath\mytempfolder\"
アップロードの実行を許可するには、フォルダーに対する権限を付与する必要があります。付与する必要がある権限は、オペレーティングシステムによって異なります。