HttpURLConnection: java.lang.IllegalStateException: уже подключено

Я пытаюсь использовать HttpURLClient для отправки некоторых данных POST на сервер, используя класс HttpRestClient, показанный ниже. При выполнении

conn.setDoInput(true);

Я получаю

java.lang.IllegalStateException: Already connected

Я удалил приложение и по-прежнему получаю ту же ошибку.

Во всем примере, который я видел, openConnection вызывается до setDoInput. Если, как следует из его названия, openConnection открывает соединение, оно никогда не должно использоваться до `setDoInput, правильно? Что мне не хватает?

Возможно, в какой-то момент он разбился перед выполнением disconnect. Может быть, это и есть причина? Если да, как отключить старое соединение?

public class HttpRestClient {
static public int post(String urlStr, List<NameValuePair> data){

    HttpURLConnection conn = null;

    try {

        URL url = new URL(urlStr);


        conn = (HttpURLConnection) url.openConnection();

        conn.setDoInput(true);
        conn.setDoOutput(true);

        conn.setRequestMethod("POST");

        OutputStream os = conn.getOutputStream();
        BufferedWriter writer = new BufferedWriter(
                new OutputStreamWriter(os, "UTF-8"));
        writer.write(getQuery(data));
        writer.flush();
        writer.close();
        os.close();

        InputStream is = conn.getInputStream();

        String dude = readIt(is);

        return 1;

    } catch (MalformedURLException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        return 0;
    } catch (IOException e) {
        // TODO Auto-generated catch block
        e.printStackTrace();
        return 0;
    }
    finally {
        if(conn!=null) conn.disconnect();
    }
}
}

Ответ 1

Это может быть связано с тем, что часы во время отладки в вашей среде IDE. См. этот ответ. Это случилось со мной и было трудно обнаружить.

Ответ 2

Вы вызывали оба conn.setDoInput(true); и conn.setDoOutput(true);. Используйте один из них:

  • setDoOutput(true) используется для запросов POST и PUT.
  • setDoInput(true) используется для запроса GET.

Соединение, которое вы создали, было смущено, оно не может решить, какой запрос следует использовать.

В вашем коде:

static public int post(String urlStr, List<NameValuePair> data){
    HttpURLConnection conn = null;
    System.setProperty("http.keepAlive", "false"); // must be set
    try {
        ...
        conn.setDoOutput(true);
        conn.setRequestMethod("POST");
        // and connect to server, if needed
        conn.connect();
        ...
    }
....

Ответ 3

Это может быть ложным исключением. Смотрите этот дефект для Джерси-2 https://java.net/jira/browse/JERSEY-2729

Ссылка была обновлена: https://github.com/jersey/jersey/issues/3001

В основном проблема заключается в том, что Джерси выбрасывал недопустимое исключение. Реальная проблема в моем случае состояла в том, что соединение было отклонено с сервера.