# http request



## Didi_R (22. Jan 2010)

hi,
ich soll ein request unter eine URL machen, ich hab kein plan davon, und wäre für hilfe dankbar!

Die URL: http://193.168.178.1/httpdpost

Unter der eben genannten URL soll ein Request mit einem Content-Type = 'multipart/form-data' gemacht werden, damit der Webserver reagiert. Es werden 2 Werte als Daten akzeptiert, wobei der erste 'YourDoc' pflicht ist, der zweite ('User') ist optional.

für YourDoc: 

Dieser Parameter muss zum einen 'filename' liefern und als Wert den Namen der Datei (ist vaiable) haben und zum anderen die Datei selbst als 'application/octet-stream' anliefern. Schematisch sieht dies wie folgt aus:

-----------------------------SHEJSXYZ usw.
Content-Disposition: form-data; name="YourDoc"; filename="myfilename.pdf"
Content-Type: application/octet-stream

ABCDEFGHIJKLMNOPYRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPYRSTUVWXYZabcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPYRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPYRSTUVWXYZabcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPYRSTUVWXYZabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPYRSTUVWXYZabcdefghijklmnopqrstuvwxyz
<...>
-----------------------------SHEJSXYZ usw. --


Wenn die Anfrage korrekt gestellt wurde, bekomme ich ein andere Datei zurück die ich dann speichern muss (der Content-Type der Response ist 'application/pdf' ).

Wie gesagt, ich habe kein ahnung wie ich davor gehen soll, wenn mir jemand ein Beispiel geben könnte, ist das super!
Bislang habe ich den commons httpclient verwendet, bisherigen code kann ich nicht liefern weil ich da nur im dunklem rumstochere!

gruß
didi


----------



## ARadauer (22. Jan 2010)

so ungefähr...


```
String url = "http://193.168.178.1/httpdpost";
PostMethod filePost = new PostMethod(url);

Part[] parts = { //hier deine parameter.. ich schicke einen user/password und ein xml file mit...
               new StringPart("login", user),
               new StringPart("pass", password),
               new FilePart("xml", file)
         };  

filePost.setRequestEntity(
               new MultipartRequestEntity(parts, filePost.getParams())
         );

HttpClient client = new HttpClient();
 int status = client.executeMethod(filePost);
         
         if (status == HttpStatus.SC_OK) {
            LOG.info("Received: "+status+" "+HttpStatus.getStatusText(status));
         } else {
            LOG.error("Received: "+status+" "+HttpStatus.getStatusText(status));
         }
         String result = filePost.getResponseBodyAsString();
...
```
usw...


----------



## maki (22. Jan 2010)

Kennst du den RFC 1521 schon? 
RFC 1521 (rfc1521) - MIME (Multipurpose Internet Mail Extensions) Part One

Binärdaten werden zum senden über HTTP in Base64 konvertiert.

Bessere antworten gibt es für bessere Problembeschreibungen.
Ein "hab keine Ahnung was ich machen soll" ist zwar ehrlich, stellt aber keine Frage dar


----------



## ARadauer (22. Jan 2010)

asso pdf speichern.... ja dann ist String result = filePost.getResponseBodyAsString(); blödsinn...

so halt irgendwie filePost.getResponseBodyAsStream() und den stream in ein File speichern, dann wird das schon klappen...


----------



## Didi_R (22. Jan 2010)

Erstmal danke euch beiden, ich werde ich mir das mal anschauen!




maki hat gesagt.:


> Kennst du den RFC 1521 schon?
> RFC 1521 (rfc1521) - MIME (Multipurpose Internet Mail Extensions) Part One
> 
> Binärdaten werden zum senden über HTTP in Base64 konvertiert.
> ...



Sorry das ich kein Fragzeichen eingefügt habe! Nächstes mal formuliere ich den satz um bzgl. ob mir jemand ein Beispiel für einen Ansatz geben kann damit dort ein Fragezeichen steht!


----------



## Didi_R (25. Jan 2010)

Also ich habe immer noch ein problem, weil ich es nicht kapiere oder so.
folgenden code den ich mehr oder weniger dank ARadauer hab:


```
File file = new File("c:/temp/test.pdf");

try{
	String url = "http://192.168.178.1/httpdpost";
	PostMethod filePost = new PostMethod(url);

	StringBuilder sb = new StringBuilder();
	sb.append("-----------------------------SHEJSF8SGBOUNDARY\n");
	sb.append("Content-Disposition: form-data; name=\"PDFfile\"; filename=\"");
	sb.append(file.getName());
	sb.append("\"\n");
	sb.append("Content-Type: application/octet-stream\n");

	Part[] parts = {
               new StringPart("PDFfile", sb.toString()),
               new FilePart(FilePart.DEFAULT_CONTENT_TYPE, file)
               
         };  
	
	filePost.setRequestEntity(
               new MultipartRequestEntity(parts, filePost.getParams())
	         );
	 
	HttpClient client = new HttpClient();
	 int status = client.executeMethod(filePost);
	         
     if (status == HttpStatus.SC_OK) {
        System.out.println("Received: "+status+" "+HttpStatus.getStatusText(status));
     } else {
    	System.out.println("Received: "+status+" "+HttpStatus.getStatusText(status));
     }
     InputStream input = filePost.getResponseBodyAsStream();

     System.err.println("Test");
     
}catch(Exception e){
	e.printStackTrace();
}
```


Das mit dem PDF-Anhang läuft falsch! denke mal das ich die Datei einlesen muss und an den Paramter anfüge! Aber vielleicht habt ihr eine Idee! Denke mal das sonst der Ansatz oben richtig ist, da dass Log vom Server folgendes nur sagt:

2010-01-25 09:16:39  INFO: WEB [9] Client request from 192.168.178.5 > "POST /httpdpost" -> Method "POST" accepted.
2010-01-25 09:16:40  ERR: WEB [9] POSTDataReceived: Unable to retrieve PDFfile content (EBadRequest)



Danke für eure Hilfe!
Falls jemand 5 min Zeit hat, kann ich ihm auch per PM den link geben was ich da machen soll, damit es evtl. schneller geht!

Gruß didi


----------



## ARadauer (25. Jan 2010)

da hast du was falsch verstanden.. dieses

```
sb.append("-----------------------------SHEJSF8SGBOUNDARY\n");
    sb.append("Content-Disposition: form-data; name=\"PDFfile\"; filename=\"");
    sb.append(file.getName());
    sb.append("\"\n");
    sb.append("Content-Type: application/octet-stream\n");
```
kannst du dir sparen... dafür ist unsere httpclient Bibliothek zuständig.

ein 
	
	
	
	





```
Part[] parts = {
            new FilePart("PDFfile", file)               
         };
```
müsste reichen.

Die boundary, Content-Disposition, Content-Type usw... alles was zum http header dazu gehört... das wird von httpclient erstellt


Besorg dir mal wireshark und schau dir an was du an den server schickst...
Und ich würde mir auf jeden fall mal das durchlesen Hypertext Transfer Protocol ? Wikipedia dann hast du mal ein bisschen Ahnung von dem was da im Hintergrund abläuft...


----------



## Didi_R (25. Jan 2010)

verdammt, auf das gleiche bin ich auch gerade gekommen!


```
new FilePart("PDFfile", FilePart.DEFAULT_CONTENT_TYPE, file)
```
 hat mich erstmal weitergebracht!

setze Thread erstmal auf erledigt, mache ihn nochmal auf wenn ich weitere hilfe brauche!

Vielen dank erstmal


----------



## Didi_R (26. Jan 2010)

So, das funktioniert jetzt alles super,
jetzt habe ich das nächste Problem

das ganze soll noch über einen weiteren Weg funktionieren und zwar mit Authentifizierung!

Ich habe folgende Dateien, die ich zum testen verwenden kann:

- DemoUser.pem --> the client certificate for authentication and SSL tunneling
in PEM format (Base64 codec).

- DemoUser.cer --> the client certificate for authentication and SSL tunneling
in DER binary format.

- DemoUser.key --> private key file for DemoUser.cer


Hier meine Code ohne Authentifizierung:


```
String url = "https://192.168.178.1/httpdpost";
PostMethod filePost = new PostMethod(url);

Part[] parts = { new FilePart("PDFfile", file) };

filePost.setRequestEntity(new MultipartRequestEntity(parts,
		filePost.getParams()));

HttpClient client = new HttpClient();

int status = client.executeMethod(filePost);

...
```

Ich habe versucht mit HttpClient - HttpClient SSL Guide weiter zukommen, 
aber ich verstehe nicht wie ich das mit den oben genannten Zertifikaten zusammen bringen soll!

Hoffe nochmal auf eure Hilfe!

gruß
didi


----------



## Didi_R (27. Jan 2010)

hmm, bin leider noch nicht weitergekommen.

hat den keiner ein beipiel oder ein tutorial wo alles von dem durchgenommen wird was ich brauche?

gruß
didi


----------



## ARadauer (29. Jan 2010)

zur Vollständigkeit hier meine PM auch noch rein:

kenn ich mich leider auch nicht gut aus...
Welche Fehlermeldung bekommst du genau?
Musst du das cert lokal instlalieren?
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

Das hat bei mir mal geklappt... ich wollte aber das Cert nicht installieren, da mir mir das auf einem Server läuft dann hab ich das probiert: HttpClient - HttpClient SSL Guide

das hat bei mir auch geklappt...


----------



## Didi_R (29. Jan 2010)

ARadauer hat gesagt.:


> zur Vollständigkeit hier meine PM auch noch rein:
> 
> kenn ich mich leider auch nicht gut aus...
> Welche Fehlermeldung bekommst du genau?
> ...



Hi,
also ich habe jetzt das Zertifikat importiert!
einmal 
[c]keytool -import -v -alias cacert -file DemoBenutzer.cer -storepass mypass -keystore DemoBenutzer.key[/c]

Dann habe ich mein Programm gestarte, er bleibt bei 
[c]int status = client.executeMethod(filePost);[/c] stehen!

Nach 4 minuten kommt eine Fehlermeldung:


```
javax.net.ssl.SSLException: Received close_notify during handshake
	at com.sun.net.ssl.internal.ssl.BaseSSLSocketImpl.a(DashoA12275)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.a(DashoA12275)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.a(DashoA12275)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.b(DashoA12275)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.a(DashoA12275)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.j(DashoA12275)
	at com.sun.net.ssl.internal.ssl.SSLSocketImpl.a(DashoA12275)
	at com.sun.net.ssl.internal.ssl.AppOutputStream.write(DashoA12275)
	at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:66)
	at java.io.BufferedOutputStream.write(BufferedOutputStream.java:105)
	at org.apache.commons.httpclient.WireLogOutputStream.write(WireLogOutputStream.java:68)
	at org.apache.commons.httpclient.methods.multipart.FilePart.sendData(FilePart.java:223)
	at org.apache.commons.httpclient.methods.multipart.Part.send(Part.java:312)
	at org.apache.commons.httpclient.methods.multipart.Part.sendParts(Part.java:385)
	at org.apache.commons.httpclient.methods.multipart.MultipartRequestEntity.writeRequest(MultipartRequestEntity.java:164)
	at org.apache.commons.httpclient.methods.EntityEnclosingMethod.writeRequestBody(EntityEnclosingMethod.java:499)
	at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:2114)
	at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:1096)
	at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:398)
	at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:171)
	at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:397)
	at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:323)
```

Ich habe das gefühl das mein ansatz schon falsch ist

gruß
didi


----------

