其实一般的只要设置一个 BasicScheme 加在 DefaultHttpClient 上面即可进行 BasicAuth 认证, 但是这个简单的方法会出现一些问题, 就是需要进行认证的请求, httpClient都不会在第一次请求服务器的时候携带认证信息, 而是在请求一次被服务器拒绝后再重新发一次请求重新进行认证. 从而导致了重复请求的问题.
通过抓包显示, DefaultHttpClient 里面的是储存了 auth 信息(用户名/密码)的, 但是所有HTTP请求都几乎会做了两遍, 第一次返回 401 unauthorized , 然后 defaultHttpClient 马上进行第二次重复请求, 添加了 auth 信息, 才返回200, 而使用 curl 进行对同样网址进行认证请求时抓包, 结果都是只进行一个请求, 直接返回200, 由此得到了 DefaultHttpClient 在进行 BasicAuth 的这个问题.
唯一的原因只有是 HttpClient 的配置问题, 在查找了大量的关于 org.apache.http.impl.client.DefaultHttpClient 相关资料后才发现正确的配置方法, 可以说是较为复杂的.
先贴代码片段, 注意这里的代码未经过删减, 是我参与的 安能饭否 项目中的实际代码:
/**
* Setup DefaultHttpClient
*
* <p>
* Use ThreadSafeClientConnManager.
* </p>
*
*/
private void prepareHttpClient() {
// Create and initialize HTTP parameters
HttpParams params = new BasicHttpParams();
ConnManagerParams.setMaxTotalConnections(params, 10);
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
// Create and initialize scheme registry
SchemeRegistry schemeRegistry = new SchemeRegistry();
schemeRegistry.register(new Scheme("http", PlainSocketFactory
.getSocketFactory(), 80));
schemeRegistry.register(new Scheme("https", SSLSocketFactory
.getSocketFactory(), 443));
// Create an HttpClient with the ThreadSafeClientConnManager.
ClientConnectionManager cm = new ThreadSafeClientConnManager(params,
schemeRegistry);
mClient = new DefaultHttpClient(cm, params);
// TODO: need to release this connection in httpRequest()
// cm.releaseConnection(conn, validDuration, timeUnit);
// Setup BasicAuth
BasicScheme basicScheme = new BasicScheme();
mAuthScope = new AuthScope(SERVER_HOST, AuthScope.ANY_PORT);
// mClient.setAuthSchemes(authRegistry);
mClient.setCredentialsProvider(new BasicCredentialsProvider());
// Generate BASIC scheme object and stick it to the local
// execution context
localcontext = new BasicHttpContext();
localcontext.setAttribute("preemptive-auth", basicScheme);
// first request interceptor
mClient.addRequestInterceptor(preemptiveAuth, 0);
}
/**
* HttpRequestInterceptor for DefaultHttpClient
*/
private HttpRequestInterceptor preemptiveAuth = new HttpRequestInterceptor() {
@Override
public void process(final HttpRequest request, final HttpContext context) {
AuthState authState = (AuthState) context
.getAttribute(ClientContext.TARGET_AUTH_STATE);
CredentialsProvider credsProvider = (CredentialsProvider) context
.getAttribute(ClientContext.CREDS_PROVIDER);
HttpHost targetHost = (HttpHost) context
.getAttribute(ExecutionContext.HTTP_TARGET_HOST);
if (authState.getAuthScheme() == null) {
AuthScope authScope = new AuthScope(targetHost.getHostName(),
targetHost.getPort());
Credentials creds = credsProvider.getCredentials(authScope);
if (creds != null) {
authState.setAuthScheme(new BasicScheme());
authState.setCredentials(creds);
}
}
}
};
/**
* Setup Credentials for HTTP Basic Auth
*
* @param username
* @param password
*/
public void setCredentials(String username, String password) {
mUserId = username;
mPassword = password;
mClient.getCredentialsProvider().setCredentials(mAuthScope,
new UsernamePasswordCredentials(username, password));
isAuthenticationEnabled = true;
}
这里并没有太多可以解释的, 目前看来是进行 BasicAuth 的基本配置, 直接搬去用就可以了. 如果说流量和请求对你的项目来说是一种负担的话.
// first request interceptor
mClient.addRequestInterceptor(preemptiveAuth, 0);
这里会在 httpClient 发出第一次请求前把anth信息强行添加到请求中去, 从而避免了重复请求.
分享到:
相关推荐
这个"DefaultHttpClient_httpsDemo"的实例,主要展示了在Android应用中如何使用`DefaultHttpClient`进行HTTPS请求,并通过自定义的`SSLSocketFactory`绕过安全检查,以适应非标准的服务器证书。然而,需要注意的是,...
《DefaultHttpClient的深度解析》 在Java开发中,网络通信是一个不可或缺的部分,而Apache HttpClient库则是其中的一个常用工具。特别是`DefaultHttpClient`类,它是HttpClient库中的核心组件,提供了丰富的HTTP...
在使用HttpClient发送POST请求时,我们需要关心两个方面的问题:一是如何忽略证书验证过程,二是如何发送POST请求。对于前者,我们可以使用X509TrustManager来忽略证书验证过程。对于后者,我们可以使用HttpPost对象...
### Java HttpClient 发送GET请求和带有表单参数的POST请求详解 #### 一、概述 在Java编程中,处理HTTP请求是一项常见的需求,特别是在与Web服务进行交互时。Apache HttpClient库提供了一种强大的方法来执行HTTP...
### JAVA发送HttpClient请求及接收请求结果过程 #### 一、概述 在Java开发过程中,经常需要与外部系统进行HTTP通信,比如发送POST或GET请求来获取数据或提交数据。Apache HttpClient是一个强大的HTTP客户端库,提供...
根据给定的部分内容,下面对每一部分进行详细解析: 1. **初始化HTTP客户端**: ```java HttpClient httpClient = new DefaultHttpClient(); ``` 使用默认的`HttpClient`实例创建HTTP客户端。 2. **设置信任...
Java 使用 HttpClient 发送 POST 请求是网络编程中常见的任务,尤其在与 Web 服务进行交互时。Apache HttpClient 是一个强大的库,允许 Java 开发者轻松地执行 HTTP 请求。在这个示例中,我们将深入探讨如何使用 ...
使用HttpURLConnection进行联网请求的基本步骤如下: 1. **建立连接**:通过URL对象创建HttpURLConnection实例。 2. **设置请求方法**:调用`setRequestMethod()`,如`setRequestMethod("POST")`或`...
DefaultHttpClient httpClient = new DefaultHttpClient(cm, params); ``` 6. **发起HTTPS请求**:现在HttpClient已经配置好,可以正常发送HTTPS请求了。例如,发送GET请求: ```java ...
尤其是在跨服务器请求时,如果涉及到中文字符的传递,很容易出现乱码问题。本文将详细介绍如何通过Java代码解决后台发起HTTP请求时中文乱码的问题。 #### 一、理解HTTP请求中文乱码的原因 在进行HTTP请求时,如果...
本篇文章将详细讲解如何在Android应用中实现POST请求,获取JSON内容并进行解析。 首先,我们需要引入网络请求库。Android SDK自带了HttpURLConnection,但使用起来较为复杂,因此开发者通常会选择第三方库,如...
本文将详细介绍Android开发中常用的几种网络请求方式,并以GET和POST请求为例进行具体说明。 #### 一、Android网络请求的基础概念 在开始介绍具体的请求方式之前,我们先来了解一些基本概念。 - **HTTP...
在Android应用开发中,网络请求是必不可少的一部分,用于获取服务器数据、更新用户界面或执行其他与互联网相关的任务。本教程将深入讲解如何使用`android-async-http`开源框架来实现异步网络请求,以实现高效的...
在网络请求过程中,可能会遇到各种错误,例如网络连接问题、超时等。需要适当地处理这些异常。同时,为了提高性能和减少资源消耗,可以通过`BasicHttpParams`或`PoolingHttpClientConnectionManager`来管理连接池。 ...
在本主题中,我们将深入探讨如何利用HttpClient实现异步请求数据,并结合Android的Asynctask进行多线程处理,以避免阻塞UI线程。 首先,我们需要理解HttpClient的基本使用。HttpClient的核心组件包括`HttpClient`...
使用HttpURLConnection进行GET请求,通常涉及以下步骤: - 打开连接:`URL url = new URL("http://example.com"); HttpURLConnection connection = (HttpURLConnection) url.openConnection();` - 设置请求方法:`...
本教程将聚焦于使用`HttpClient`库进行GET请求,这是获取远程资源最常见的方式。请注意,本教程不涉及POST请求,POST主要用于向服务器提交数据。 ## 1. Android HttpClient介绍 `HttpClient`是Apache HTTP组件的一...
本篇将详细讲解如何使用`HttpClient`进行异步请求数据,并结合Android的`AsyncTask`来处理后台任务,避免阻塞UI线程。 首先,理解`HttpClient`的基本使用方法。`HttpClient`包含几个关键组件,如`HttpClient`实例、...
本文将详细介绍如何使用HttpClient在Android中实现网络请求,并通过Cookie来维持会话状态,以便进行持久化的用户登录。 首先,我们需要了解HttpClient的基本用法。HttpClient是一个强大的HTTP客户端库,它允许...