HTTP POST в Java (с загрузкой файла) - PullRequest
15 голосов
/ 14 марта 2012

Что я хочу сделать, это отправить веб-форму из Java-приложения. Форма, которую мне нужно заполнить, находится здесь: http://cando -dna-origami.org /

Когда форма отправлена, сервер отправляет электронное письмо с подтверждением на указанный адрес электронной почты, который на данный момент я просто проверяю вручную. Я попытался заполнить форму вручную, и письма отправляются нормально. (Следует также отметить, что при неправильном заполнении формы страница просто обновляется и не дает никаких отзывов).

Я никогда ничего не делал с http раньше, но я некоторое время оглядывался по сторонам и придумал следующий код, который должен отправлять POST-запрос на сервер:

    String data = "name=M+V&affiliation=Company&email="
            + URLEncoder.encode("m.v@gmail.com", "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();

Однако, когда он запускается, он, похоже, ничего не делает - то есть я не получаю никаких писем, хотя программа выводит «200 OK» в System.out, что, кажется, указывает на то, что что-то получено с сервера, хотя я не уверен, что именно это означает. Я думаю, что проблема может заключаться в загрузке файла, так как я не был уверен, требуется ли для этого типа данных другой формат.

Это правильный способ отправки запроса POST с использованием Java? Нужно ли делать что-то другое для загрузки файла? Спасибо!


Прочитав пост Адама, я использовал Apache 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);

Однако, похоже, он все еще не работает; Опять же, я не был уверен, как загруженный файл вписывается в форму, поэтому я попытался просто отправить два отдельных запроса POST, один с формой и один с другими данными. Я все еще ищу способ объединить их в один запрос; Кто-нибудь знает что-нибудь об этом?

Ответы [ 5 ]

17 голосов
/ 14 марта 2012

Возможно, вам было бы лучше использовать что-то вроде Apache HttpClient , с помощью которого вы можете программно создать POST запрос.

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

Если вам нужно загрузить файл вместе с вашей формой, вам нужно будет использовать MultipartEntity вместо:

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

httpost.setEntity(reqEntity);

На их сайте есть несколько примеров программ . «Вход в систему на основе форм» и «Объект запроса, состоящий из нескольких частей» являются хорошими примерами для начала.

Возможно, стоит проверить ваши соединения и взглянуть на базовые данные сети, чтобы увидеть, что происходит. Что-то вроде Firebug позволит вам точно видеть, что происходит в вашем браузере, и вы можете включить ведение журнала HttpClient, чтобы увидеть все данные, которыми обмениваются в вашей программе. Кроме того, вы можете использовать что-то вроде Wireshark или Fiddler для наблюдения за вашим сетевым трафиком в режиме реального времени. Это может дать вам лучшее представление о том, что именно делает ваш браузер, по сравнению с тем, что делает ваша программа.

2 голосов
/ 14 июля 2013

Вы должны окончательно использовать apaches HTTPClient для этой работы!Это делает жизнь намного проще.Вот пример, как загрузить файл с помощью Apache 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());

Дайте мне знать, если у вас есть дополнительные вопросы.

1 голос
/ 18 октября 2017

Поскольку большая часть предлагаемого кода запроса Java HTTP POST там не работает, я решил дать вам полностью работоспособный код, который, я уверен, вы найдете полезным для создания любого запроса POST на основе Java в будущем.

Этот запрос POST имеет тип multipart, чтобы разрешить отправку / загрузку файла на сервер.

Многокомпонентный запрос состоит из основного заголовка и строки разделителя с именем border , чтобы отличить каждую часть от другой (этот разделитель будет идти в потоке со строкой "-" (две черты) перед ней, и каждая часть имеет свой собственный маленький заголовок, чтобы сообщить свой тип и некоторые другие метаданные.

Моя задача состояла в том, чтобы создать файл PDF с использованием некоторых онлайн-сервисов, но все составные примеры POST просто не помогли ...

Мне нужно было упаковать документ HTML вместе с его фотографиями, файлами JS и CSS в файл ZIP / TAR, загрузить его в онлайн-сервис преобразования html2pdf и получить результат в виде документа PDF обратно мне в качестве ответа (поток) ) из службы.

Текущий сервис, который я проверил, используя следующий код: Htmlpdfapi.com , но я уверен, что с небольшими изменениями вы сможете использовать его с любым другим сервисом.

Вызов метода (для этой службы) выглядит примерно так: [class instance name].sendPOSTRequest("http://htmlpdfapi.com/api/v1/pdf", "Token 6hr4-AmqZDrFVjAcJGykjYyXfwG1wER4", "/home/user/project/srv/files/example.zip", "result.pdf");

Вот мой код, который был проверен и работает на 100%:

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

}
1 голос
/ 14 марта 2012

В настоящее время я пишу небольшой веб-сервер и проверил ваш клиентский запрос.Мой сервер получает следующий запрос:

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

Вы должны проверить формат отправляемых вами данных POST, скорее всего, они не будут обработаны сервером так, как вы ожидаете.

0 голосов
/ 21 мая 2015

Вот пример, который я получил, который использует apache httpclient.Также не забудьте добавить следующие зависимости:

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

Код: HttpClient httpclient = HttpClientBuilder.create (). Build ();

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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...