2012-03-13 18 views
14

Lo que quiero hacer es enviar un formulario web desde una aplicación java. El formulario que necesito completar se encuentra aquí: http://cando-dna-origami.org/Http POST en Java (con carga de archivos)

Cuando se envía el formulario, el servidor envía un correo electrónico de confirmación a la dirección de correo electrónico indicada, que por ahora solo estoy verificando a mano. He intentado completar el formulario de forma manual y los correos electrónicos se envían bien. (También se debe tener en cuenta que cuando el formulario se rellena de manera incorrecta, la página se actualiza y no da ningún comentario).

que nunca he hecho nada con http antes, pero me miraron a su alrededor por un tiempo, y se acercó con el siguiente código, que se supone debe enviar una solicitud POST al servidor:

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(); 

Sin embargo , cuando se ejecuta, parece que no hace nada, es decir, no recibo ningún correo electrónico, aunque el programa imprime "200 OK" en System.out, lo que parece indicar que se recibió algo del servidor, aunque no estoy seguro de lo que significa exactamente. Creo que el problema podría estar en la carga del archivo, ya que no estaba seguro de si ese tipo de datos requería un formato diferente.

¿Es esta la forma correcta de enviar una solicitud POST utilizando Java? ¿Debo hacer algo diferente para la carga del archivo? ¡Gracias!


Después de leer el post de Adam, he utilizado Apache y escribió el siguiente código HttpClient:

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

Sin embargo, todavía no parece estar funcionando; una vez más, no estaba seguro de cómo encajaba el archivo cargado en el formulario, así que intenté enviar dos solicitudes POST separadas, una con el formulario y otra con los demás datos. Todavía estoy buscando una manera de combinar esto en una sola solicitud; ¿Alguien sabe algo sobre esto?

Respuesta

17

Probablemente sea mejor que utilice algo como Apache HttpClient, con el que puede generar una solicitud POST mediante programación.

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

Si necesita cargar un archivo junto con su formulario, usted tendrá que usar una vez MultipartEntity:

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

httpost.setEntity(reqEntity); 

Hay algunos programas de ejemplo sobre el their site. El "inicio de sesión basado en el formulario" y la "entidad de solicitud codificada en varias partes" son buenos ejemplos para comenzar.

También puede valer la pena probar sus conexiones y echar un vistazo a los datos de la red subyacente para ver qué está sucediendo. Algo como Firebug le permitirá ver exactamente lo que está sucediendo en su navegador, y puede activar el registro de HttpClient para ver todos los datos intercambiados en su programa. Alternativamente, puede usar algo como Wireshark o Fiddler para ver el tráfico de su red en tiempo real. Esto puede darle una mejor idea de lo que está haciendo exactamente su navegador, en comparación con lo que está haciendo su programa.

+0

Gracias por su consejo! Descargué Apache HttpClient y escribí un código diferente usando eso; desafortunadamente, todavía no parece estar haciendo nada. El problema sigue siendo que no estoy seguro de cómo combinar el formulario y la carga del archivo. Ver arriba – Reyan

+0

Así que sugiero que eche un vistazo a los datos subyacentes que atraviesan la conexión HTTP (el último párrafo de mi respuesta), ya que eso aclarará las diferencias entre el uso del navegador (que está funcionando) y su programa (que no es no funciona) –

+0

Ahora veo. Actualicé la respuesta con información sobre cómo agregar una carga de archivo. –

1

Actualmente estoy escribiendo un pequeño servidor web y probé su cliente de solicitud. Mi servidor recibe la petición siguiente:

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 

debe comprobar el formato de los datos de POST que está enviando, más probable es que no es procesada por el servidor como era de esperar.

+0

¡Gracias por su respuesta y por probar el código! ¿A qué se refiere exactamente con "los datos POST" que estoy enviando? ¿Quiere decir solo los datos del formulario, o también los datos del cliente y de la conexión? Lamento decir que no entiendo la importancia de la información que publicaste en el cuadro de códigos. ¿Hay algún problema con la configuración de conexión? – Reyan

+0

Me refería a la variable "datos" con los datos del formulario. Los datos del cuadro representan los encabezados y el contenido recibido por el servidor. – Alex

2

¡Definitivamente debe utilizar apaches HTTPClient para ese trabajo! Hace la vida mucho más facil. Aquí hay un ejemplo de cómo cargar un archivo con apaches HttpClient.

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()); 

Deseo saber si tiene más preguntas.

0

Aquí hay un ejemplo que obtuve trabajando que utiliza apache httpclient. Además, no se olvide de añadir estas dependencias:

<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> 

El código:. HttpClient httpclient = HttpClientBuilder.create() construcción();

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

Como la mayor parte del código de solicitud POST HTTP Java sugerido por ahí no es operativa, decidí darle mi código en pleno funcionamiento que estoy seguro de que encontrará muy útil para crear cualquier solicitud POST basada en Java en el futuro.

Esta solicitud POST es del tipo multipart para permitir el envío/carga de un archivo en el servidor.

petición de varias partes constan de una cabecera principal y una cadena de separación llamada límite para contar cada parte del otro (este separador vendrán en la corriente con "-" (dos guiones) antes de que la cadena, y cada parte tiene su propia pequeña cabecera para contar su tipo y algunos meta-datos más.

Mi tarea era crear un archivo PDF utilizando algunos servicios en línea, pero todos los ejemplos de la POST de varias partes simplemente no hacer el truco ...

Necesitaba empacar un documento HTML junto con sus imágenes, archivos JS y CSS en un archivo ZIP/TAR, subirlo a un servicio de conversión en línea html2pdf y obtener el resultado como un documento PDF de nuevo a mí como la respuesta (transmisión) del servicio.

El servicio actual que he comprobado usando el siguiente código es: Htmlpdfapi.com pero estoy seguro de que con ajustes menores podrá usarlo con cualquier otro servicio.

La llamada método (para ese servicio) se ve algo como: [class instance name].sendPOSTRequest("http://htmlpdfapi.com/api/v1/pdf", "Token 6hr4-AmqZDrFVjAcJGykjYyXfwG1wER4", "/home/user/project/srv/files/example.zip", "result.pdf");

Aquí está mi código que se comprobó y 100% obras:

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

}