2012-03-13 8 views
14

Quello che voglio fare è inviare un modulo web da un'applicazione java. Il modulo che ho bisogno di compilare si trova qui: http://cando-dna-origami.org/Http POST in Java (con upload di file)

Quando il modulo viene inviato, il server invia una e-mail di conferma all'indirizzo di posta elettronica indicato, che per ora sto solo controllando a mano. Ho provato a compilare il modulo manualmente e le e-mail vengono inviate correttamente. (Va anche notato che quando il modulo è compilato in modo errato, la pagina si aggiorna e non fornisce alcun feedback).

non ho mai fatto nulla con http prima, ma mi sono guardato intorno per un po ', e si avvicinò con il seguente codice, che dovrebbe inviare una richiesta POST al server:

String data = "name=M+V&affiliation=Company&email=" 
      + URLEncoder.encode("[email protected]", "UTF-8") 
      + "&axialRise=0.34&helixDiameter=2.25&axialStiffness=1100&bendingStiffness=230" + 
      "&torsionalStiffness=460&nickStiffness=0.01&resolution=course&jsonUpload=" 
      + URLEncoder.encode("C:/Users/Marjie/Downloads/twisted_DNA_bundles/monotwist.L1.v1.json", 
      "UTF-8") + "&type=square"; 

    URL page = new URL("http://cando-dna-origami.org/"); 
    HttpURLConnection con = (HttpURLConnection) page.openConnection(); 

    con.setDoOutput(true); 
    con.setRequestMethod("POST"); 
    con.connect(); 

    OutputStreamWriter out = new OutputStreamWriter(con.getOutputStream()); 
    out.write(data); 
    out.flush(); 

    System.out.println(con.getResponseCode()); 
    System.out.println(con.getResponseMessage()); 

    out.close(); 
    con.disconnect(); 

Tuttavia , quando viene eseguito non sembra fare nulla - cioè, non ricevo nessuna email, anche se il programma stampa "200 OK" su System.out, che sembra indicare che qualcosa è stato ricevuto dal server, anche se non sono sicuro di cosa significhi esattamente. Penso che il problema potrebbe essere nel caricamento dei file, dal momento che non ero sicuro che quel tipo di dati richiedesse un formato diverso.

È un modo corretto di inviare una richiesta POST utilizzando Java? Devo fare qualcosa di diverso per il caricamento dei file? Grazie!


Dopo aver letto il post di Adam, ho usato Apache HttpClient e ha scritto il seguente codice:

List<NameValuePair> params = new ArrayList<NameValuePair>(); 
    params.add(new BasicNameValuePair("type", "square")); 
    //... add more parameters 

    UrlEncodedFormEntity entity = new UrlEncodedFormEntity(params, HTTP.UTF_8); 

    HttpPost post = new HttpPost("http://cando-dna-origami.org/"); 
    post.setEntity(entity); 

    HttpResponse response = new DefaultHttpClient().execute(post); 
    post = new HttpPost("http://cando-dna-origami.org/"); 

    post.setEntity(new FileEntity(new File("C:/Users/Marjie/Downloads/twisted_DNA_bundles/monotwist.L1.v1.json"), "text/plain; charset=\"UTF-8\"")); 
    HttpResponse responseTwo = new DefaultHttpClient().execute(post); 

Tuttavia, ancora non sembra essere di lavoro; di nuovo, non ero sicuro di come il file caricato si inserisse nel modulo, quindi ho provato a inviare solo due richieste POST separate, una con il modulo e una con gli altri dati. Sto ancora cercando un modo per combinarli in un'unica richiesta; qualcuno sa qualcosa di questo?

risposta

17

Probabilmente starai meglio usando qualcosa come Apache HttpClient, con cui puoi creare una richiesta POST programmaticamente.

HttpClient httpclient = new DefaultHttpClient(); 
HttpPost httppost = new HttpPost("http://.../whatever"); 

List <NameValuePair> params = new ArrayList<NameValuePair>(); 
params.add(new BasicNameValuePair("param1", "value1")); 
params.add(new BasicNameValuePair("param2", "value2")); 
... 

httpost.setEntity(new UrlEncodedFormEntity(params, HTTP.UTF_8)); 

HttpResponse response = httpclient.execute(httppost); 

Se è necessario caricare un file con il modulo, è necessario utilizzare un MultipartEntity invece:

MultipartEntity reqEntity = new MultipartEntity(); 
reqEntity.addPart("someParam", "someValue"); 
reqEntity.addPart("someFile", new FileBody("/some/file")); 
.... 

httpost.setEntity(reqEntity); 

Ci sono alcuni programmi di esempio sopra su their site. "Accesso basato su modulo" e "Entità richiesta codificata multipart" sono buoni esempi da cui partire.

Può anche essere utile il test fuori le connessioni e dare un'occhiata ai dati di rete sottostante per vedere cosa sta succedendo. Qualcosa come Firebug ti permetterà di vedere esattamente cosa sta succedendo nel tuo browser, e puoi attivare la registrazione HttpClient per vedere tutti i dati scambiati nel tuo programma. In alternativa, puoi usare qualcosa come Wireshark o Fiddler per guardare il traffico di rete in tempo reale. Questo potrebbe darti un'idea migliore di ciò che sta facendo il tuo browser, rispetto a ciò che sta facendo il tuo programma.

+0

Grazie per i vostri consigli! Ho scaricato Apache HttpClient e ho scritto un altro pezzo di codice usando quello; sfortunatamente sembra che non stia ancora facendo nulla. Il problema è ancora che non sono sicuro di come combinare il modulo e il caricamento del file. Vedi sopra – Reyan

+0

Quindi ti suggerisco di dare un'occhiata ai dati sottostanti che attraversano la connessione HTTP (l'ultimo paragrafo della mia risposta), in quanto ciò chiarirà le differenze tra l'uso del browser (che funziona) e il tuo programma (che non è funziona) –

+0

Ora capisco. Ho aggiornato la risposta con informazioni sull'aggiunta di un caricamento di file. –

1

Attualmente sto scrivendo un piccolo server Web e ho testato il client di richiesta. Il mio server sta ricevendo la seguente richiesta:

User-Agent: Java/1.6.0_20 
Host: localhost:1700 
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2 
Connection: keep-alive 
Content-type: application/x-www-form-urlencoded 
Content-Length: 287 
name=M+V&affiliation=Company&email=m.v%40gmail.com&axialRise=0.34&helixDiameter=2.25&axialStiffness=1100&bendingStiffness=230&torsionalStiffness=460&nickStiffness=0.01&resolution=course&jsonUpload=C%3A%2FUsers%2FMarjie%2FDownloads%2Ftwisted_DNA_bundles%2Fmonotwist.L1.v1.json&type=square 

si dovrebbe verificare il formato dei dati POST si sta inviando, molto probabilmente non viene elaborato dal server come ci si aspetterebbe.

+0

Grazie per la risposta e per testare il codice! Cosa intendi esattamente per "i dati POST" che sto inviando? Intendi solo i dati del modulo, o anche il cliente e i dati di connessione? Mi dispiace dirlo, non capisco il significato delle informazioni che hai postato nella casella del codice. C'è qualcosa di sbagliato nelle impostazioni di connessione? – Reyan

+0

Mi riferivo alla variabile "dati" con i dati del modulo. I dati dalla casella rappresentano le intestazioni e il contenuto ricevuto dal server. – Alex

2

Si dovrebbe usare definitivamente apaches HTTPClient per quel lavoro! Rende la vita molto più facile. Ecco un esempio di come caricare un file con HttpClient apaches.

byte[] data = outStream.toByteArray() 
HttpClient client = new DefaultHttpClient(); 
HttpPost httpPost = new HttpPost("http://localhost:8080/YourResource"); 

ByteArrayBody byteArrayBody = new ByteArrayBody(data, "application/json", "some.json"); 
MultipartEntity multipartEntity = new MultipartEntity(); 
multipartEntity.addPart("upload", byteArrayBody); 
httpPost.setEntity(multipartEntity); 

HttpResponse response = client.execute(httpPost); 
Reader reader = new InputStreamReader(response.getEntity().getContent()); 

Fatemi sapere se avete ulteriori domande.

0

Ecco un esempio di funzionamento che utilizza apache httpclient. Inoltre, non dimenticare di aggiungere queste dipendenze:

<dependency> 
     <groupId>org.apache.httpcomponents</groupId> 
     <artifactId>httpclient</artifactId> 
     <version>4.4.1</version> 
    </dependency> 


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

Il codice:. HttpClient httpclient = HttpClientBuilder.create() costruire();

HttpPost httppost = new HttpPost(DataSources.TORRENT_UPLOAD_URL); 

MultipartEntityBuilder builder = MultipartEntityBuilder.create(); 
      builder.addPart("a_field_name", new FileBody(torrentFile)); 

HttpEntity entity = builder.build(); 

httppost.setEntity(entity); 

HttpResponse response = httpclient.execute(httppost); 
1

Come la maggior parte del codice di richiesta HTTP POST Java suggerito là fuori non è operativo, ho deciso di dare il mio codice completamente operativo che io sono sicuro che troverete utile per creare qualsiasi richiesta POST basato su Java nel futuro.

Questa richiesta POST è del tipo multipart per consentire l'invio/caricamento di un file sul server.

richiesta Multipart costituiti da un collettore principale e una stringa di separazione chiamato confine di raccontare ogni parte dall'altra (questo separatore arriverà nel flusso con "-" (due trattini) stringa prima di esso, ed ogni parte ha il suo piccolo colpo di testa da raccontare il tipo e un po 'di meta-dati.

il mio compito era quello di creare un file PDF utilizzando alcuni servizi on-line, ma tutti gli esempi POST multipart semplicemente non fare il trucco ...

Avevo bisogno di impacchettare un documento HTML con le sue immagini, i file JS e CSS in un file ZIP/TAR, caricarlo su un servizio di conversione html2pdf online e ottenere il risultato come documento PDF mi viene restituito come risposta (stream) dal servizio.

Il servizio corrente che ho controllato utilizzando il seguente codice è: Htmlpdfapi.com ma sono sicuro che con piccole modifiche sarete in grado di usarlo con qualsiasi altro servizio.

Il chiamata al metodo (per quel servizio) sembra qualcosa di simile: [class instance name].sendPOSTRequest("http://htmlpdfapi.com/api/v1/pdf", "Token 6hr4-AmqZDrFVjAcJGykjYyXfwG1wER4", "/home/user/project/srv/files/example.zip", "result.pdf");

Ecco il mio codice che è stato estratto e il 100% opere:

public void sendPOSTRequest(String url, String authData, String attachmentFilePath, String outputFilePathName) 
{ 
    String charset = "UTF-8"; 
    File binaryFile = new File(attachmentFilePath); 
    String boundary = "------------------------" + Long.toHexString(System.currentTimeMillis()); // Just generate some unique random value. 
    String CRLF = "\r\n"; // Line separator required by multipart/form-data. 
    int responseCode = 0; 

    try 
    { 
     //Set POST general headers along with the boundary string (the seperator string of each part) 
     URLConnection connection = new URL(url).openConnection(); 
     connection.setDoOutput(true); 
     connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary); 
     connection.addRequestProperty("User-Agent", "CheckpaySrv/1.0.0"); 
     connection.addRequestProperty("Accept", "*/*"); 
     connection.addRequestProperty("Authentication", authData); 

     OutputStream output = connection.getOutputStream(); 
     PrintWriter writer = new PrintWriter(new OutputStreamWriter(output, charset), true); 

     // Send binary file - part 
     // Part header 
     writer.append("--" + boundary).append(CRLF); 
     writer.append("Content-Disposition: form-data; name=\"file\"; filename=\"" + binaryFile.getName() + "\"").append(CRLF); 
     writer.append("Content-Type: application/octet-stream").append(CRLF);// + URLConnection.guessContentTypeFromName(binaryFile.getName())).append(CRLF); 
     writer.append(CRLF).flush(); 

     // File data 
     Files.copy(binaryFile.toPath(), output); 
     output.flush(); 

     // End of multipart/form-data. 
     writer.append(CRLF).append("--" + boundary + "--").flush(); 

     responseCode = ((HttpURLConnection) connection).getResponseCode(); 


     if(responseCode !=200) //We operate only on HTTP code 200 
      return; 

     InputStream Instream = ((HttpURLConnection) connection).getInputStream(); 

     // Write PDF file 
     BufferedInputStream BISin = new BufferedInputStream(Instream); 
     FileOutputStream FOSfile = new FileOutputStream(outputFilePathName); 
     BufferedOutputStream out = new BufferedOutputStream(FOSfile); 

     int i; 
     while ((i = BISin.read()) != -1) { 
      out.write(i); 
     } 

     // Cleanup 
     out.flush(); 
     out.close(); 


    } 
    catch(Exception e) 
    { 
     e.printStackTrace(); 
    } 

}