HttpURLConnection: java.lang.IllegalStateException

2019-04-06 08:28发布

问题:

I'm trying to use HttpURLClient to send some POST data to a server using the HttpRestClient class shown below. When executing

conn.setDoInput(true);

I get

java.lang.IllegalStateException: Already connected

I uninstalled the app, and still get the same error.

In all the example I've seen openConnection is called before setDoInput. If, as its name suggests, openConnection opens a connection, it should never be used before `setDoInput, right? What am I missing?

Maybe at some point it crashed before executing disconnect. Could that be the reason? If so, how can I disconnect the old connection?

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:

This might be due to watches while debugging in your IDE. See this answer. It happened to me and was hard to discover.



回答2:

You called both of conn.setDoInput(true); and conn.setDoOutput(true);. Use one of them:

  • setDoOutput(true) is used for POST and PUT requests.
  • setDoInput(true) is used for GET request.

The connection you made was confused, it can't decide which request should be used.

In your code:

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:

It may be a misleading exception. See this defect for Jersey-2 https://java.net/jira/browse/JERSEY-2729