“Connection already established” exception in HttpsURLConnection

半腔热情 提交于 2019-12-20 01:09:29

问题


I am trying to do a POST request using HttpsURLConnection, and get

java.net.ProtocolException: Connection already established

on setRequestMethod Weirdly, conn.connected returns false just before.

What am I missing?

URL url = new URL("https://ws.audioscrobbler.com/2.0/");
HttpsURLConnection conn = (HttpsURLConnection) url.openConnection();
conn.setReadTimeout(15000);
conn.setConnectTimeout(15000);
// here conn.connected is false
conn.setRequestMethod("POST"); // here I get java.net.ProtocolException: Connection already established
conn.setDoInput(true);

EDIT

I tried DefaultHttpClient and it works, so I'll use it instead.


回答1:


For anyone else who runs into this problem, I had an order of operations issue that only affected me when I was doing an HTTP POST that had content in the request body. It's not entirely clear in all scenarios when HttpURLConnection is actually initiating the connection to the server.

My initial request looked like this:

        HttpURLConnection conn = null;
        try
        {
            conn = (HttpURLConnection) baseUrl.openConnection();  
            conn.setConnectTimeout(connectTimeoutMillis);
            conn.setReadTimeout(requestTimeoutMillis);

            //required for reading a response body
            conn.setDoInput(true);

            //Not all request types have a body (e.g. GET usually doesn't)
            if(requestBody != null && requestBody.length > 0)
            {
                conn.setDoOutput(true);
                conn.setFixedLengthStreamingMode(requestBody.length);
                conn.getOutputStream().write(requestBody);
                conn.getOutputStream().flush();
                conn.getOutputStream().close();
            }

            try
            {
                conn.setRequestMethod(verb.toUpperCase());
            }
            catch (final ProtocolException e)
            {
                response.setError("Invalid HTTP verb \"" + verb + "\" received.","");
                Log.e(TAG, response.errorMessage, e);
                return response;
            }

It turns out that you cannot call "conn.setRequestMethod(...)" after you've called "conn.getOutputStream()", so in my case, the simple fix was the call "conn.setRequestMethod(...)" before dealing with writing to the request body. The working code is:

HttpURLConnection conn = null;
        try
        {
            conn = (HttpURLConnection) baseUrl.openConnection();  
            conn.setConnectTimeout(connectTimeoutMillis);
            conn.setReadTimeout(requestTimeoutMillis);

            //required for reading a response body
            conn.setDoInput(true);

            try
            {
                conn.setRequestMethod(verb.toUpperCase());
            }
            catch (final ProtocolException e)
            {
                response.setError("Invalid HTTP verb \"" + verb + "\" received.","");
                Log.e(TAG, response.errorMessage, e);
                return response;
            }

            //Not all request types have a body (e.g. GET usually doesn't)
            if(requestBody != null && requestBody.length > 0)
            {
                conn.setDoOutput(true);
                conn.setFixedLengthStreamingMode(requestBody.length);
                conn.getOutputStream().write(requestBody);
                conn.getOutputStream().flush();
                conn.getOutputStream().close();
            }

The only real change was just switching the ordering of calls and that got rid of the exception. Hopefully that fixes the issue for anyone else who had this problem.




回答2:


I tried DefaultHttpClient and it works, so I'll use it instead.



来源:https://stackoverflow.com/questions/17984368/connection-already-established-exception-in-httpsurlconnection

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!