Java.io.IOException:在ICS 4.0.3中接收的身份验证挑战为空

6
我正在尝试从服务器注销。但是它返回带有此异常的“0”响应代码。我使用GET动词来执行此操作。
LogCat
10-17 14:54:13.261: W/System.err(868): java.io.IOException: Received authentication challenge is null
10-17 14:54:13.284: W/System.err(868):  at libcore.net.http.HttpURLConnectionImpl.processAuthHeader(HttpURLConnectionImpl.java:397)
10-17 14:54:13.284: W/System.err(868):  at libcore.net.http.HttpURLConnectionImpl.processResponseHeaders(HttpURLConnectionImpl.java:345)
10-17 14:54:13.304: W/System.err(868):  at libcore.net.http.HttpURLConnectionImpl.getResponse(HttpURLConnectionImpl.java:276)
10-17 14:54:13.324: W/System.err(868):  at libcore.net.http.HttpURLConnectionImpl.getResponseCode(HttpURLConnectionImpl.java:479)
10-17 14:54:13.324: W/System.err(868):  at com.remote.synchronizer.haris.CustomHttpClient.executeGet(CustomHttpClient.java:131)
10-17 14:54:13.354: W/System.err(868):  at com.remote.synchronizer.haris.OptionsActivity$1$3$1.run(OptionsActivity.java:87)
10-17 14:54:13.364: W/System.err(868):  at android.os.Handler.handleCallback(Handler.java:605)
10-17 14:54:13.384: W/System.err(868):  at android.os.Handler.dispatchMessage(Handler.java:92)
10-17 14:54:13.384: W/System.err(868):  at android.os.Looper.loop(Looper.java:137)
10-17 14:54:13.404: W/System.err(868):  at android.app.ActivityThread.main(ActivityThread.java:4424)
10-17 14:54:13.424: W/System.err(868):  at java.lang.reflect.Method.invokeNative(Native Method)
10-17 14:54:13.424: W/System.err(868):  at java.lang.reflect.Method.invoke(Method.java:511)
10-17 14:54:13.454: W/System.err(868):  at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:784)
10-17 14:54:13.474: W/System.err(868):  at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:551)
10-17 14:54:13.474: W/System.err(868):  at dalvik.system.NativeStart.main(Native Method)
10-17 14:54:13.484: E/HTTP Response(868): java.io.IOException: Received authentication challenge is null

CustomHttpClient.java

public class CustomHttpClient {

    static HttpClient client = new DefaultHttpClient();
    static HttpURLConnection connection = null; 

    public static int executePost(String url, String postParameters)
    {
        int response=0;

        OutputStream output = null;
        try
        {
            connection = (HttpURLConnection)new URL(url).openConnection();
            System.setProperty("http.keepAlive", "false");
            connection.setDoOutput(true);
            connection.setRequestMethod("POST");
            connection.setRequestProperty("Accept-Charset", "UTF-8");
            connection.setRequestProperty("Content-Type", "application/x-www-form-urlencoded;charset=UTF-8");

            connection.connect();

            output = connection.getOutputStream();
            output.write(postParameters.getBytes("UTF-8"));

            response=connection.getResponseCode();
        }
        catch(Exception e)
        {
            e.printStackTrace();
            Log.e("HTTP Response", e.toString());
        }
        finally {
            if(connection != null) {
                //  connection.disconnect(); 
                if (output != null) 
                    try { output.close(); } 
                catch (IOException logOrIgnore) {}
            }
        }

        return response;
    }

    public static int executeGet(String url)
    {
        int response=0;

        //HttpURLConnection connection = null;
        try
        {
            connection = (HttpURLConnection) new URL(url).openConnection();
            System.setProperty("http.keepAlive", "false");
            //connection.setRequestProperty("Accept-Charset", "UTF-8");
            connection.setDoInput(true);
            connection.setRequestMethod("GET");
            connection.connect();
            response=connection.getResponseCode();
        } 
        catch(Exception e)
        {
            e.printStackTrace();
            Log.e("HTTP Response", e.toString());
        }
        finally {
            if(connection != null) {
                //  connection.disconnect();
            }
        }
        return response;
    }

}

之前我在Gingerbird 2.3中使用DefaultHTTPClient,它完美地工作了。但是在ICS中,DefaultHTTPClient不起作用,所以我需要使用HttpURLConnection。POST动词可以正常工作。


请查看我的回复,如果您喜欢它,请点赞或接受! - Erik Živković
你可能已经看到了这个问题,但分享一下也值得一试:https://dev59.com/iGgt5IYBdhLWcg3wywdJ - Emmanuel
3个回答

9

如果您在连接对象上第二次调用.getResponseCode(),则可以在异常后获得响应代码。这是因为第一次调用.getResponseCode()会设置内部状态,使.getResponseCode()能够返回而不抛出异常。

示例:

HttpURLConnection connection = ...;
try {
    // Will throw IOException if server responds with 401.
    connection.getResponseCode(); 
} catch (IOException e) {
    // Will return 401, because now connection has the correct internal state.
    int responsecode = connection.getResponseCode(); 
}

我在这里也回答了这个问题:https://dev59.com/8mPVa4cB1Zd3GeqP5Wng#15972969


3
HttpURLConnection.getResponseCode()在遇到畸形HTTP 401头时会抛出java.io.IOException: Received authentication challenge is null。除HTTP/1.1 401 Unauthorized头外,您是否还从服务器接收WWW-AuthenticateContent-Length头?如果出现问题,请参见IOException:"Received authentication challenge is null" (Apache Harmony / Android)。如果无法更改服务器,则可以捕获该异常(感谢https://dev59.com/8mPVa4cB1Zd3GeqP5Wng#10904318)。
try {
    response=connection.getResponseCode();
}
catch (java.io.IOException e) {
    if (e.getMessage().contains("authentication challenge")) {
        response = HttpsURLConnection.HTTP_UNAUTHORIZED;
    } else { throw e; }
}

1

这个错误是因为服务器发送了一个401(未授权)但没有给出“WWW-Authenticate”,这是提示客户端下一步该做什么的提示。 “WWW-Authenticate”标头告诉客户端需要哪种身份验证(BasicDigest)。这在无头HTTP客户端中通常不是很有用,但这就是标准定义的方式。错误发生是因为库尝试解析“WWW-Authenticate”标头但无法解析。

如果您可以更改服务器,则可能的解决方案:

  • 添加一个虚假的“WWW-Authenticate”标头,如:WWW-Authenticate:Basic realm =“fake”。这只是一个解决方法而不是解决方案,但它应该有效并且HTTP客户端满意。
  • 使用HTTP状态代码403而不是401。其语义不同,通常在使用登录时,401是正确的响应(请参阅此处进行详细讨论),但足够接近。

如果您无法更改服务器,则可能的解决方案:

正如@ErikZ在他的post中所写的那样,您可以使用try&catch。

HttpURLConnection connection = ...;
try {
    // Will throw IOException if server responds with 401.
    connection.getResponseCode(); 
} catch (IOException e) {
    // Will return 401, because now connection has the correct internal state.
    int responsecode = connection.getResponseCode(); 
}

我也在这里发布了:java.io.IOException:未找到身份验证挑战


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接