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