Требуется ли от сервера запись данных на сервер с использованием класса URL-адресов Java? - PullRequest
1 голос
/ 22 декабря 2010

Я пытаюсь загрузить файлы, используя класс Java URL, и обнаружил предыдущий вопрос о переполнении стека, который очень хорошо объясняет детали, поэтому я стараюсь следовать ему. И ниже мой код, взятый из фрагмента, приведенного в ответе .

Моя проблема заключается в том, что если я не позвоню одному из connection.getResponseCode() или connection.getInputStream() или connection.getResponseMessage() или чему-либо, что связано с ответом с сервера, запрос никогда не будет быть отправлено на сервер. Зачем мне это делать? Или есть ли способ записи данных без получения ответа?

P.S. Я разработал сервлет загрузки на стороне сервера, который принимает multipart/form-data и сохраняет его в файлы, используя FileUpload. Он стабилен и определенно работает без проблем, поэтому моя проблема не в этом.

import java.io.Closeable;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import org.apache.commons.io.IOUtils;

public class URLUploader {

    public static void closeQuietly(Closeable... objs) {
        for (Closeable closeable : objs) {
            IOUtils.closeQuietly(closeable);
        }
    }

    public static void main(String[] args) throws IOException {
        File textFile = new File("D:\\file.zip");
        String boundary = Long.toHexString(System.currentTimeMillis()); // Just generate some unique random value.

        HttpURLConnection connection = (HttpURLConnection) new URL("http://localhost:8080/upslet/upload").openConnection();
        connection.setDoOutput(true);
        connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary);
        OutputStream output = connection.getOutputStream();

        PrintWriter writer = new PrintWriter(output, true);
        // Send text file.
        writer.println("--" + boundary);
        writer.println("Content-Disposition: form-data; name=\"file1\"; filename=\"" + textFile.getName() + "\"");
        writer.println("Content-Type: application/octet-stream");
        FileInputStream fin = new FileInputStream(textFile);
        writer.println();
        IOUtils.copy(fin, output);
        writer.println();
        // End of multipart/form-data.
        writer.println("--" + boundary + "--");
        output.flush();
        closeQuietly(fin, writer, output);
        // Above request will never be sent if .getInputStream() or .getResponseCode() or .getResponseMessage() does not get called.
        connection.getResponseCode();
    }
}

Ответы [ 3 ]

1 голос
/ 22 декабря 2010

HttpURLConnection имеет несколько сеттеров, которые влияют на запрос, поэтому он должен знать, когда вы закончите сборку запроса, чтобы он мог отослать его.Это происходит путем ожидания, пока вы на самом деле не запросите что-то из запроса, например InputStream.(Это, возможно, конструктивный недостаток.) ​​Именно поэтому установщики выдают исключение IllegalStateException «если он уже подключен» - когда вы вызываете метод получения, соединение устанавливается, и уже слишком поздно вызывать метод установки.должен быть в состоянии вызвать getInputStream(), а затем просто close(), не читая с него.

0 голосов
/ 08 февраля 2012

для тех, кто проверяет этот фрагмент, есть строка, которую я считаю неправильной:

OutputStream output = output = connection.getOutputStream();

проверьте это;)
Кстати, это правда, что вы должны использовать метод getResponseCode()пытаясь обработать исключение при установлении соединения, это хорошо, если вы убедитесь, что ваше соединение работает должным образом.

0 голосов
/ 23 декабря 2010

Просто вызовите getResponseCode (). Это будет инициировать передачу. В любом случае вы должны сделать это, чтобы убедиться, что запрос выполнен успешно или выяснить, почему он не прошел.

...