如何在没有使用android中的try / catch处理它的情况下获得401响应

时间:2012-07-31 08:01:45

标签: android httpurlconnection

我正在使用HttpUrlConnection从我的Android应用程序发出网络请求。一切正常,除了一件事,401。每当服务器返回状态代码为401的响应时,我的应用程序抛出IOException,并显示一条消息,指出"no authentication challenge found"。谷歌搜索后,我还没有找到一个解决方案,但只能解决方法(使用try / catch处理它,假设它有401响应)。

这是代码段:

public Bundle request(String action, Bundle params, String cookie) throws FileNotFoundException, MalformedURLException, SocketTimeoutException,
        IOException {

    OutputStream os;

    String url = baseUrl + action;
    Log.d(TAG, url);
    HttpURLConnection conn = (HttpURLConnection) new URL(url).openConnection();
    conn.setConnectTimeout(30 * 1000);
    conn.setReadTimeout(30 * 1000);
    conn.setRequestProperty("User-Agent", System.getProperties().getProperty("http.agent") + "AndroidNative");
    conn.setRequestMethod("POST");
    conn.setRequestProperty("Content-Type", "multipart/form-data;boundary=" + boundary);
    conn.setRequestProperty("Connection", "Keep-Alive");
    conn.setDoOutput(true);
    conn.setDoInput(true);
    if (cookie != null) {
        conn.setRequestProperty("Cookie", cookie);
    }

    if (params != null) {
        os = conn.getOutputStream();
        os.write(("--" + boundary + endLine).getBytes());
        os.write((encodePostBody(params, boundary)).getBytes());
        os.write((endLine + "--" + boundary + endLine).getBytes());
        uploadFile(params, os);
        os.flush();
        os.close();
    }

    conn.connect();

    Bundle response = new Bundle();
    try {
        response.putInt("response_code", conn.getResponseCode());
        Log.d(TAG, conn.getResponseCode() + "");
        response.putString("json_response", read(conn.getInputStream()));
        List<String> responseCookie = conn.getHeaderFields().get("set-cookie");
        // Log.d(TAG, responseCookie.get(responseCookie.size() - 1));
        response.putString("cookie", responseCookie.get(responseCookie.size() - 1));
    } catch (SocketTimeoutException e) {
        throw new SocketTimeoutException(e.getLocalizedMessage());
    } catch (FileNotFoundException e) {
        throw new FileNotFoundException(e.getLocalizedMessage());
    } catch (IOException e) {
        e.printStackTrace();
        response.putInt("response_code", HttpURLConnection.HTTP_UNAUTHORIZED);
        response.putString("json_response", read(conn.getErrorStream()));
    }

    // debug
    Map<String, List<String>> map = conn.getHeaderFields();
    for (String key : map.keySet()) {
        List<String> values = map.get(key);
        for (String value : values) {
            Log.d(key, value);
        }
    }

    conn.disconnect();

    return response;
}

我真的想知道,为什么抛出这个异常?认证挑战意味着什么?如何提供身份验证挑战?我必须在我的代码中做出哪些改变来克服这种情况?

请赐教......:)

2 个答案:

答案 0 :(得分:13)

IOException是一个非常普遍的例外,每次抛出它都不能安全地假设401状态代码。

如果第一次请求状态代码时它恰好包含401,HttpURLConnection将抛出IOException。此时,连接的内部状态将发生变化,现在它将能够为您提供状态代码,而不会出现任何错误。

int status = 0;
try {
    status = conn.getResponseCode();
} catch (IOException e) {
    // HttpUrlConnection will throw an IOException if any 4XX
    // response is sent. If we request the status again, this
    // time the internal status will be properly set, and we'll be
    // able to retrieve it.
    status = conn.getResponseCode();
}
if (status == 401) {
    // ...
}

有关详细信息,请http://www.tbray.org/ongoing/When/201x/2012/01/17/HttpURLConnection

答案 1 :(得分:-2)

尝试使用HttpClient

private void setCredentials(String login, String password) {
    if (login != null && password != null)
        httpClient.getCredentialsProvider().setCredentials(
                new AuthScope(URL_HOST, 80), new UsernamePasswordCredentials(login, password));

}



private InputStream execute(String url, String login, String password) {
        setCredentials(login, password);
        HttpGet get = new HttpGet(url);
        try {
            HttpResponse response = httpClient.execute(get);
            int code = response.getStatusLine().getStatusCode();
            if (code == HttpURLConnection.HTTP_OK) {
                InputStream stream = response.getEntity().getContent();
                return stream;
            } else {
                Log.e("TAG", "Wrong response code " + code + " for request " + get.getRequestLine().toString());
                return null;
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }