Garip bir sorun - Java HttpClient PHP ile çalışan kütüphane kullanarak bir dosya yüklemek için nasıl

5 Cevap java

PHP ile Apache sunucuya bir dosya upload edecek, Java uygulaması yazmak istiyorum. Java kodu Jakarta HttpClient kütüphanesinin sürüm 4.0 beta2 kullanır:

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 dosyası upload.php çok basittir:

<?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);
}
?>

Reading the response I get the following result: executing request POST http://localhost:9002/upload.php HTTP/1.1

HTTP/1.1 200 OK
Possible file upload attack: filename ''.
Array
(
)

Yani isteği ben sunucu ile iletişim kurabilmek, başarılı oldu, ancak PHP dosyası fark etmedi - yöntemi is_uploaded_file false döndürdü ve $ _FILES değişken boştur. Ben bu happend olabilir neden hiçbir fikrim yok. HTTP yanıtı ve isteği izlenir ve onlar Tamam bak: istek

POST /upload.php HTTP/1.1
Content-Length: 13091
Content-Type: binary/octet-stream
Host: localhost:9002
Connection: Keep-Alive
User-Agent: Apache-HttpClient/4.0-beta2 (java 1.5)
Expect: 100-Continue

˙Ř˙ŕ..... the rest of the binary file...

ve yanıtı:

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

Possible file upload attack: filename ''.Array
(
)

Ben xampp ve uzaktan Linux sunucu ile hem yerel windows xp bu test edildi. Ancak $ _FILES dizi uygun veri ile doluydu, ve sonuç daha belirsiz, is_uploaded_file false döndürdü - versiyon 3.1 - Ben de HttpClient önceki bir sürümünü kullanmaya çalıştık.

5 Cevap

Tamam, ben kullanılan Java kodu yanlış olduğunu, burada sağ Java sınıfı geliyor:

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 kullanarak unutmayın.

Kullanmaya çalışan kişiler için bir güncelleştirme MultipartEntity ...

org.apache.http.entity.mime.MultipartEntity 4.3.1 önerilmiyor.

Sen MultipartEntityBuilder HttpEntity nesnesi oluşturmak için kullanabilirsiniz.

File file = new File();

HttpEntity httpEntity = MultipartEntityBuilder.create()
    .addBinaryBody("file", file, ContentType.create("image/jpeg"), file.getName())
    .build();

Maven kullanıcılar için sınıf (sadece bir sonraki sürümü ile fervisa cevabı olarak hemen hemen aynı) aşağıdaki bağımlılık mevcuttur.

<dependency>
  <groupId>org.apache.httpcomponents</groupId>
  <artifactId>httpmime</artifactId>
  <version>4.3.1</version>
</dependency>

Doğru yolu çok yapraklı POST yöntemini kullanmak olacaktır. here istemci için örnek kod için bkz.

PHP için pek çok dersler vardır. Bu first benim bulduğum. Ben bir html istemcisi kullanarak ilk PHP kodu test ve ardından java istemci denemenizi öneririz.

Ben aynı sorun koştu ve HttpClient 4.x PHP arka uç ile çalışmaktan için dosya adı gerekli olduğunu öğrendim. Bu HttpClient 3.x için durum böyle değildi

So my solution is to add a name parameter in the FileBody constructor. ContentBody cbFile = new FileBody(file, "image/jpeg", "FILE_NAME");

Umarım yardımcı olur.

Eğer yerel WAMP bu test eğer dosya yüklemeleri için geçici klasör ayarlamak gerekebilir. Eğer php.ini dosyasında yapabilirsiniz:

upload_tmp_dir = "c:\mypath\mytempfolder\"

Eğer vermeniz gereken izni işletim sistemine göre değişiklik - Sen yükleme gerçekleşmesi için izin klasörün izinleri gerekir.