gpt4 book ai didi

java - HttpURLConnection.getRequestProperties() 抛出 IllegalStateException : "Already connected"

转载 作者:太空宇宙 更新时间:2023-11-03 12:32:20 26 4
gpt4 key购买 nike

执行请求后,我想检查请求 header ,但它不起作用。

我在 sun.net.www.protocol.http.HttpURLConnection 的一个实例上调用了 getRequestProperties(),我总是收到 IllegalStateException 消息“已经连接” .好像我想设置请求属性。但我只想阅读它们。

负责此行为的代码在 HttpUrlConnection 中:
http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/sun/net/www/protocol/http/HttpURLConnection.java#HttpURLConnection.getRequestProperties%28%29

public synchronized Map<String, List<String>> getRequestProperties() {
if (connected)
throw new IllegalStateException("Already connected");
// ...
}

好吧,也许我应该只在断开连接后读取请求属性。但事实证明,disconnect() 并未将 connected 设置为 false。虽然它应该:http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/7u40-b43/sun/net/www/protocol/http/HttpURLConnection.java#HttpURLConnection.disconnect%28%29

我是否读完流似乎也没有什么区别。在调用 disconnect 之前或之后关闭 InputStream 也没有什么不同。

我很困惑。你能帮帮我吗?

  1. 为什么 disconnect() 没有设置 connected 为 false?
  2. 为什么在连接 urlConnection 时我无法读取请求属性?
  3. 如何在请求后正确读取请求 header ?

重现此代码是 Android 的单元测试(我使用 Robolectric),但我认为您也可以在 Java 项目中使用它并在删除测试注释后从 main() 调用它:

/**
* Test if HttpUrlConnection works as expected, because in some cases it seems it doesn't
*
* @throws Exception
*/
@Test
public void testHttpUrlConnection() throws Exception
{
final URL url = new URL("http://www.stackoverflow.com");
final HttpURLConnection urlConnection = ( HttpURLConnection ) url.openConnection( );
urlConnection.setRequestMethod("GET");
InputStream is = null;
try
{
is = urlConnection.getInputStream();
assertEquals(200, urlConnection.getResponseCode());
}
catch (IOException ex)
{
is = urlConnection.getErrorStream( );
}
final String result = copyStreamToString(is); // some html response
// Streams must be closed before disconnecting (according to http://stackoverflow.com/a/11056207/3596676)
is.close();
assertTrue((Boolean) getFieldViaRecursiveReflection(urlConnection, "connected"));
// urlConnection should always be disconnected (according to http://developer.android.com/reference/java/net/HttpURLConnection.html)
urlConnection.disconnect();
assertFalse((Boolean) getFieldViaRecursiveReflection(urlConnection, "connected")); // AssertionError
// getRequestProperties throws IllegalStateException ("already connected")
Map<String, List<String>> requestProperties = urlConnection.getRequestProperties();
// do stuff with the properties
// return the result
}

private static String copyStreamToString( final InputStream is ) throws IOException
{
if ( is == null )
{
return "";
}
BufferedReader reader = new BufferedReader( new InputStreamReader( is ) );
String result = copyBufferedReaderToString( reader );
reader.close( );
return result;
}

private static String copyBufferedReaderToString( final BufferedReader bufferedReader ) throws IOException
{
StringBuffer sb = new StringBuffer( );
String line;
while ( ( line = bufferedReader.readLine( ) ) != null )
{
sb.append( line );
}
return sb.toString( );
}

private static Object getFieldViaRecursiveReflection(final Object object, final String attribute) throws Exception
{
return getFieldViaRecursiveReflection(object, object.getClass(), attribute);
}

private static Object getFieldViaRecursiveReflection(final Object object, final Class<?> c, final String attribute) throws Exception
{
try
{
final Field field = c.getDeclaredField(attribute);
field.setAccessible(true);
return field.get(object);
}
catch (NoSuchFieldException ex)
{
/* end of type hierarchy? */
Class<?> superClass = c.getSuperclass();
if (superClass == null)
{
throw ex;
}
else
{
return getFieldViaRecursiveReflection(object, superClass, attribute);
}
}
}

最佳答案

由于我提出问题后的2个月内没有人发布答案,但今天我不得不再次处理问题并找到解决方案,我将回答我自己的问题。

我无法回答答案中的所有问题(例如“为什么 urlConnection.disconnect() 不设置 urlConnection< 的 connected 属性 to false?"),但我找到了主要问题的解决方案,即当连接 urlConnection 时读取请求的 header 不起作用。

出于某种原因,我不记得了,我想/需要在请求完成并且响应出现后检查请求 header 。但是我再次查看了 sun.net.www.protocol.http.HttpURLConnectiongetRequestProperties() 的实现(参见代码 here )并注意到一个方法called filterAndAddHeaders 被调用。因此,似乎 header 不仅在该方法中被读取,而且被设置。我不确定为什么这是在 getter 方法(getRequestProperties() 方法)中完成的,但是当请求已经完成时,您应该在用户尝试添加时警告他请求 header - 在这种情况下,IllegalStateException 非常困扰我。

得出解决方案:

我只是将对 getRequestProperties() 的调用移动到发送请求的之前。现在一切正常。

附言:

请注意,这还不是全部。即使我在请求后调用了 getRequestProperties(),我的一个单元测试还是成功运行了。在这种情况下,urlConnection 内部属性 connected 被设置为 false。我还没有完全弄清楚,但它可能与响应状态代码 304(未修改)有关。如果您必须处理此问题并且由于某种原因无法在发送请求之前移动 getRequestProperties() 调用,这可能有助于提示。

关于java - HttpURLConnection.getRequestProperties() 抛出 IllegalStateException : "Already connected",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29831347/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com