FileUpload mit commons HttpClient

FriFra

Mitglied
Hallo zusammen,

ich versuche gerade erfolglos eine Datei hoch zu laden...

HTML-Form:
HTML:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Rufnummern (Kurzwahl- und Telefonbuch)</title>
</head>

<body class="d3">
<form name="import_form" method="post" action="http://192.168.123.8/telefonbuch_kurzwahl?im_file=kurzwahlen&actionNo=12" accept-charset="ISO-8859-1" enctype="multipart/form-data">
<input type="file" name="im_file" size="70">
<input type=submit>
</form>
</body>
</html>

Mein Java-Code sieht wie folgt aus:
Java:
...
				httpost = new HttpPost(sURL+"/telefonbuch_kurzwahl?im_file=kurzwahlen&actionNo=12");
				File file = new File("d:/rufnummern.txt");
				FileEntity reqEntity = new FileEntity(file, "binary/octet-stream");
				httpost.setEntity(reqEntity);
				reqEntity.setContentType("binary/octet-stream");
				System.out.println("executing request " + httpost.getRequestLine());

			
			     response = httpclient.execute(httpost);			     
	     		entity = response.getEntity();
				System.out.println("Status*: " + response.getStatusLine());

...


ich bekomme zwar als Status 200 OK... aber der "Upload" geht viel zu schnell und die Daten kommen auch nicht an. Was mache ich falsch?
 

FriFra

Mitglied
File Uploads macht man mit dem HttpClient - Multipart Post Method
API mit Code-Beispiel: HttpClient 3.1 API

Die sind allerdings nicht in import org.apache.http. ... enthalten, sondern in org.apache.commons.httpclient. ... Ich kann irgendwie kein funktionierendes Beispiel finden... entweder muss man raten, welche imports noch fehlen, oder es funktioniert einfach nicht.
Gibt es denn kein Beispiel? Ich kann auf der unter "Code-Beispiel" genannten Seite kein Beispiel finden...
 

kay73

Bekanntes Mitglied
Ich kann auf der unter "Code-Beispiel" genannten Seite kein Beispiel finden...

Sorry. Hier:
MultipartRequestEntity (HttpClient 3.1 API)
Java:
  File f = new File("/path/fileToUpload.txt");
  PostMethod filePost = new PostMethod("http://host/some_path");
  Part[] parts = {
      new StringPart("param_name", "value"),
      new FilePart(f.getName(), f)
  };
  filePost.setRequestEntity(
      new MultipartRequestEntity(parts, filePost.getParams())
      );
  HttpClient client = new HttpClient();
  int status = client.executeMethod(filePost);
 

FriFra

Mitglied
Hab jetzt folgenden Code:
Java:
				httpclient.getParams().setParameter(CoreProtocolPNames.PROTOCOL_VERSION, HttpVersion.HTTP_1_1);

				HttpPost httppost = new HttpPost(sURL+"/telefonbuch_kurzwahl?im_file=kurzwahlen&actionNo=12");
				File file = new File("d:/rufnummern.txt");

				MultipartEntity mpEntity = new MultipartEntity();
				ContentBody cbFile = new FileBody(file, "text/plain");
				mpEntity.addPart("im_file", cbFile);

				httppost.setEntity(mpEntity);
				System.out.println("executing request " + httppost.getRequestLine());
				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();
				}

Allerdings kommt die Datei nach wie vor nicht an...
 

kay73

Bekanntes Mitglied
Sorry, der 3er ist wohl sehr outdatet. So gehts mit 4.0.1 und Multipart (zwar schludrig aber funktioniert).

Ich kann zu Deinem Code nicht wirklich einen Unterschried entdecken; ich tippe auf
Code:
new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);
.

Die Datei wird auf jeden Fall mitgeschickt. Wenn es jetzt nicht klappt, liegt es an falschen POST-Daten oder am Netz.
Java:
package com.mycompany.app;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;

import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.HttpMultipartMode;
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;

public class App {
	public static void main(String[] args) throws IOException {
		
		final HttpClient httpclient = new DefaultHttpClient();

		final HttpPost httpPost = new HttpPost("/");

		final MultipartEntity multipartEntity = new MultipartEntity(
				HttpMultipartMode.BROWSER_COMPATIBLE);

		final ContentBody contentBody = new FileBody(new File(
				"/home/kay/Dokumente/tmp/my-app/pom.xml"), "text/plain");

		multipartEntity.addPart("upload_file", contentBody);
		httpPost.setEntity(multipartEntity);

		final HttpResponse response = httpclient.execute(new HttpHost(
				"localhost"), httpPost);

		System.out.println(response.getStatusLine());

		final HttpEntity entity = response.getEntity();

		if (entity != null) {
			final BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent()));
			System.out.println(reader.readLine());
			
			httpclient.getConnectionManager().shutdown();
		}
	}
}
 
Zuletzt bearbeitet:

FriFra

Mitglied
Leider klappt es nicht... Irgend etwas muss noch anders sein, als mit nem richtigen Browser. So wie es jetzt ist, meldet der Zielserver: "Fehler 12002: - falsche Boundary Key"
k.A. was mir die Meldung sagen will, fakt us nur, das passiert nicht, wenn ich manuell über den Browser uploade.
 

kay73

Bekanntes Mitglied
Dann musst Du den Paketverkehr mitschneiden und vergleichen. Vielleicht schummelt ein JavaScript einen Parameter in das Form, um das Uploaden für Nicht-Browser zu erschweren.

Eine "Boundary" kommt im Multipart-Standard als Trenner zwischen den Abschnitten vor; aber hieße der Client würde das Forumlar falsch formatieren. Unwahrscheinlich.
 
Zuletzt bearbeitet:

FriFra

Mitglied
Es muss doch möglich sein, den Upload eines simplen HTML-Formulars (s. erstes Post) mit diesen Komponenten zu realisieren... die URL inkl. Parameter ist korrekt und es gibt nur ein einziges Feld...

aber hieße der Client würde das Forumlar falsch formatieren. Unwahrscheinlich.
Einzige Möglichkeit! IE - kein Problem, FF - kein Problem, apache - klappt nicht ... alle mit der gleichen Datei.
 

kay73

Bekanntes Mitglied
Natürlich geht das; wird nur ein Detail sein (HTTP-Version, chunked encoding erwartet, falscher Entity-Name, User-Agent faken). Schneide halt mit wireshark die beiden POSTS mit und vergleiche sie. So habe ich schon schwierigere Formularuploads erledigt.
 
Zuletzt bearbeitet:

FriFra

Mitglied
Wireshark schmiert auf meinem Testrechner permanent ab... damit komme ich nicht weiter.

Firebug zeigt allerdigs auch nur das was man auch so schon sieht... Wie das Formular versendet wird, steht doch alles schon im Form-Tag... Das einzige, was mir noch einfallen würde, wäre das encoding, da wird im Form: ISO-8859-1, vorgegeben.
 

FriFra

Mitglied
WireShark zeigt bei mir an der entspr. Stelle überhaup keinen Request ???:L:bahnhof:
Java:
				httpost = new HttpPost(sURL+"/telefonbuch_kurzwahl?im_file=kurzwahlen&actionNo=12");

				FileBody bin = new FileBody(new File("d:/rufnummern.txt"),"text/plain");

				MultipartEntity mpentity = new MultipartEntity(HttpMultipartMode.BROWSER_COMPATIBLE);      
				mpentity.addPart("im_file", bin);
				httpost.setEntity(mpentity);
        
				System.out.println("executing request " + httpost.getRequestLine());
				System.out.println("DoPost");
				response = httpclient.execute(httpost);
				System.out.println("Done!");
				entity = response.getEntity();
				is = entity.getContent();

				System.out.println("----------------------------------------");
				System.out.println(response.getStatusLine());
				if (entity != null) {
					System.out.println("CHK: "+convertStream2String(is));
					System.out.println("Response content length: " + entity.getContentLength());
					System.out.println("Chunked?: " + entity.isChunked());
				}
				if (entity != null) {
					entity.consumeContent();
				}

Ich sehe zwar an der Java-Console, dass der Post problemlos "ausgeführt" wird... aber WireShark zeigt nichts... 2 Requests vorher und einer danach sind sichtbar, nur der Post nicht.
 

FriFra

Mitglied
Keiner eine Idee, was man da noch machen kann?

Die commons FileUpload gibt es leider z.Zt. nur auf Basis der 3er Controls... damit wäre aber alles andere, was bereits funktioniert für die Tonne.
 

kay73

Bekanntes Mitglied
Mal der Vollständigkeit halber: Untenstehender HTML-Code, PHP-Testseite und der Client in Java funktionieren. Siehe unten den Wireshark dump.

Gefährlich ist aber aber das
Code:
Expect: 100-Continue
. Z. B. lighttpd kann damit nicht umgehen. Vielleicht liegt es daran. Füge mal
Java:
httpPost.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false);
in Zeile 34 ein.


HTML:
HTML:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
	<head>
	<title>Rufnummern (Kurzwahl- und Telefonbuch)</title>
	</head>
	<body >
		<form name="import_form" method="post" action="http://localhost/test_upload.php" accept-charset="ISO-8859-1" enctype="multipart/form-data">
		<input type="file" name="im_file" size="70">
		<input type="submit">
	</form>
	</body>
</html>
PHP Testseite:
Code:
<?php

$uploaddir = '/var/www/tmp/';
$uploadfile = $uploaddir . basename($_FILES['im_file']['name']);

echo '<pre>';
if (move_uploaded_file($_FILES['im_file']['tmp_name'], $uploadfile)) {
    echo "File is valid, and was successfully uploaded.\n";
} else {
    echo "Possible file upload attack!\n";
}

echo 'Here is some more debugging info:';
print_r($_FILES);

print "</pre>";

?>
Wireshark dump
Code:
POST /test_upload.php HTTP/1.1

Content-Length: 153

Content-Type: multipart/form-data; boundary=6uDLdUrR80Phz7e4tiGaH_5cp1HXR9y

Host: localhost

Connection: Keep-Alive

User-Agent: Apache-HttpClient/4.0.1 (java 1.5)

Expect: 100-Continue



HTTP/1.1 100 Continue



--6uDLdUrR80Phz7e4tiGaH_5cp1HXR9y

Content-Disposition: form-data; name="im_file"; filename="hallo.txt"



Hallo!


--6uDLdUrR80Phz7e4tiGaH_5cp1HXR9y--

HTTP/1.1 200 OK

Date: Mon, 31 May 2010 18:11:27 GMT

Server: Apache/2.2.14 (Ubuntu)

X-Powered-By: PHP/5.3.2-1ubuntu4.2

Vary: Accept-Encoding

Content-Length: 303

Keep-Alive: timeout=15, max=100

Connection: Keep-Alive

Content-Type: text/html



<pre>File is valid, and was successfully uploaded.
Here is some more debugging info:Array
(
    [im_file] => Array
        (
            [name] => hallo.txt
            [type] => 
            [tmp_name] => /var/www/uploads/phpy6TjJt
            [error] => 0
            [size] => 7
        )

)
</pre>
Java:
package com.mycompany.app;

import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;

import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.mime.HttpMultipartMode;
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;

public class App {
	public static void main(String[] args) throws IOException {
		
		final HttpClient httpclient = new DefaultHttpClient();

		final HttpPost httpPost = new HttpPost("/test_upload.php");

		final MultipartEntity multipartEntity = new MultipartEntity(
				HttpMultipartMode.BROWSER_COMPATIBLE);

		final ContentBody contentBody = new FileBody(new File(
				"/home/kay/Dokumente/tmp/my-app/pom.xml"), "text/plain");

		multipartEntity.addPart("im_file", contentBody);
		httpPost.setEntity(multipartEntity);

		final HttpResponse response = httpclient.execute(new HttpHost(
				"localhost"), httpPost);

		System.out.println(response.getStatusLine());

		final HttpEntity entity = response.getEntity();

		if (entity != null) {
			final BufferedReader reader = new BufferedReader(new InputStreamReader(entity.getContent()));
		    final StringBuilder b = new StringBuilder();
		    String s;
		    while((s = reader.readLine()) != null) {
		    	b.append(s+"\n");
		    }
		    
		    System.out.println(b.toString());
			
			httpclient.getConnectionManager().shutdown();
		}
	}
}
 
Zuletzt bearbeitet:

FriFra

Mitglied
Füge mal
Java:
httpPost.getParams().setBooleanParameter(CoreProtocolPNames.USE_EXPECT_CONTINUE, false);
in Zeile 34 ein.

Leider bringt das auch keine Besserung...

Falls es hilft, ich hab mal den Servernamen der Webservers auf der Telefonanlage: "Server: GoAhead-Webs"


Wireshark zeigt mir beim "original" Request über die html-Seite für den encapsulated multipart part: "Line-based text data: text/plain" und dann kommt der Inhalt der Datei im Klartext. Über den httpclient bekomme ich nur: "Data (8750 bytes)" und einen encodeten Inhalt, also nicht die Textdatei im Klartext.
Im Header des multipart part steht bei beiden Requests:
"Content-Disposition: form-data; name="im_file"; filename="rufnummern.txt"\r\n\r\n"
in der funktionierenden Version steht noch:
"Content-Type: text/plain\r\n\r\n" ... dieses Header Feld fehlt im part beim httpclient.
 

FriFra

Mitglied
Es liag tatsächlich am vom Client erzeugtem Boundary... Ich habe jetzt einfach mal einen Boundary-String von einem erfolgreichen Post mit dem Browser kopiert und übergeben... jetzt klappts.
Java:
			MultipartEntity mpentity = new MultipartEntity(null,"---------------------------126372240926463",null);

Jetzt hab ich nur noch ein Timeout Problem bei größeren Dateien.
 

bennyn

Neues Mitglied
Bei mir hat folgender Code funktioniert, um eine Datei mit dem Apache HTTPClient zu senden:

Java:
import java.io.File;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.HttpVersion;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.conn.HttpHostConnectException;
import org.apache.http.entity.FileEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.params.HttpProtocolParams;
import org.apache.http.util.EntityUtils;

public class App
{

  static final Logger logger = Logger.getLogger(App.class.getPackage().getName());

  public static void main(String[] args) throws Exception
  {
    HttpParams params = new BasicHttpParams();
    params.setParameter(HttpProtocolParams.USE_EXPECT_CONTINUE, false);
    HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
    HttpClient client = new DefaultHttpClient(params);
    HttpPost post = new HttpPost("http://localhost:8080/");

    File file = new File("C:/Temp/upload/movie.avi");
    FileEntity reqEntity = new FileEntity(file, "binary/octet-stream");
    post.setEntity(reqEntity);
      HttpResponse response = client.execute(post);
      HttpEntity entity = response.getEntity();
      if (entity != null)
      {
        System.out.println(EntityUtils.toString(entity));
      }
}

Vielleicht ist die Implementierung auf der Serverseite nicht korrekt? Ich habe mir einen kleinen Fileserver mit dem JBoss Netty-Framework erstellt. Hat sehr gut funktioniert!
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
nrg FileUpload HTTP POST Netzwerkprogrammierung 5
Nuiton FTP Apache Commons: FTPClient und Sicherheit Netzwerkprogrammierung 9
S FTP Verbindung zu einem BS2000 Großrechner mit Commons Net Netzwerkprogrammierung 0
N FTP FTP Client invalid IPv6 address (Apache Commons Net API) Netzwerkprogrammierung 6
0 Apache Commons File Object bekommen Netzwerkprogrammierung 4
F Apache commons net SFTPClient Netzwerkprogrammierung 5
B FTP commons net verschlüsselte verbindung Netzwerkprogrammierung 11
M need org.apache.commons.httpclient.* Netzwerkprogrammierung 8
C apache commons net ftp bei upload unvollständig Netzwerkprogrammierung 3
T HTTP Apache Commons HttpClient Bibliothek Netzwerkprogrammierung 2
S Commons Net 2.0 und FTP in meinem Programm Netzwerkprogrammierung 4
A org.apache.commons http client in Netbeans einbinden Netzwerkprogrammierung 3
1 Upload problem! org.apache.commons.net.ftp Netzwerkprogrammierung 3
A Jakarta Commons HTTPClient: Mehrere Requests gleichzeitig Netzwerkprogrammierung 2
M [Commons NET] Prüfen, ob auf FTP Datei vorhanden ist Netzwerkprogrammierung 2
S Verzeichnis auslesen (FTP Jakarta Commons Net) Netzwerkprogrammierung 2
M org.apache.commons.httpclient.HttpClient Netzwerkprogrammierung 3
G Jakarta Net Commons - FTPClient: Problem bei Dateiupload Netzwerkprogrammierung 2
D HTTP Apache-HttpClient/UNAVAILABLE (java 1.4) Netzwerkprogrammierung 18
B HttpClient - Server (Jetty) - getInputStream - EOF Netzwerkprogrammierung 3
G apache httpClient Problem. Netzwerkprogrammierung 5
B HttpClient Netzwerkprogrammierung 2
M Apache HTTPClient Server log ausgeben ?! Netzwerkprogrammierung 3
N HTTP Apache 4.2.1 HttpClient 302 nach Login und auf den weiteren Seiten. Netzwerkprogrammierung 5
R Apache HttpClient File Download? Netzwerkprogrammierung 3
M HTTP HTTPClient Authentication - Quickr Server Netzwerkprogrammierung 8
H Java 1.4 HTTPClient Content von PutMethod Netzwerkprogrammierung 4
K Login via apache httpclient Netzwerkprogrammierung 4
P HttpClient - Daten einer Website "unvollständig" Netzwerkprogrammierung 5
M Dateiupload mittels HttpClient Netzwerkprogrammierung 3
H HTTP Login mit POSTMethod und httpClient Netzwerkprogrammierung 5
lordcarlos HTTP Apache HttpClient, post und login. Netzwerkprogrammierung 2
B HTTP Probleme mit HttpClient? Netzwerkprogrammierung 2
H Bilder mit HttpClient hochladen Netzwerkprogrammierung 3
T Apache HttpClient & Default Headers Netzwerkprogrammierung 9
T apache HTTPClient einloggen Netzwerkprogrammierung 2
T HttpClient - Senden via Post Netzwerkprogrammierung 12
M httpclient kann sich nicht auf asp.net Seite anmelden Netzwerkprogrammierung 2
Q HTTPS mit Apache HttpClient Netzwerkprogrammierung 4
M Seltsame Fehlermeldung (httpclient) Netzwerkprogrammierung 6
E HttpClient und return Problem Netzwerkprogrammierung 6
K Bad Request nach Form Login in Jakarta HttpClient Netzwerkprogrammierung 4
J Jakarta HTTPClient Netzwerkprogrammierung 5
D Problem beim holen einer PHP-Seite via HttpClient Netzwerkprogrammierung 19
C HTTPS mit Apache HTTPClient Netzwerkprogrammierung 1
S mit HttpClient Seiteninhalt lesen Netzwerkprogrammierung 8
P jakarta.HttpClient: Port bei GetMethod angeben Netzwerkprogrammierung 3

Ähnliche Java Themen

Neue Themen


Oben