原文 http://www.cnblogs.com/java-koma/archive/2013/05/22/3093309.htmlhtml
1,HttpClientjava
Win 8提供了System.Net.Http.HttpClient類進行經常使用的http網絡請求,HttpClient提供瞭如下構造函數。數組
// 摘要:
// 初始化 System.Net.Http.HttpClient 類的新實例。
public HttpClient();
//
// 摘要:
// 用特定的處理程序初始化 System.Net.Http.HttpClient 類的新實例。
//
// 參數:
// handler:
// 用於發送請求的使用的 HTTP 處理程序堆棧。
public HttpClient(HttpMessageHandler handler);
//
// 摘要:
// 用特定的處理程序初始化 System.Net.Http.HttpClient 類的新實例。
//
// 參數:
// handler:
// System.Net.Http.HttpMessageHandler 負責處理 HTTP 響應消息。
//
// disposeHandler:
// 若是內部處理程序應由 Dispose () 處理,則爲 true;若是您但願重用內部處理程序,則爲 false。
public HttpClient(HttpMessageHandler handler, bool disposeHandler);
第2個構造函數經常使用來處理在請求前添加header(如:Cookie),響應時解析header。 cookie
下面使用HttpClient處理POST/GET提交:網絡
#1. 讓咱們先來定義好key-value類型的參數,用於提交。session
public class Parameter
{
public string key { get; set; }
public string value { get; set; }
public Parameter() { }
public Parameter(string key, string value)
{
this.key = key;
this.value = value;
}
}
#2. POST/GET:異步
private static async Task<string> doRequest<T>(string url, List<Parameter> paramList, bool isPost)
{
System.Net.Http.HttpClient httpClient = null;
try
{
httpClient = new System.Net.Http.HttpClient();
httpClient.DefaultRequestHeaders.Add("user-agent", "Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; WOW64; Trident/6.0)");
HttpResponseMessage response = null;
// POST
if (isPost)
{
MultipartFormDataContent form = getPostForm(paramList);
response = await httpClient.PostAsync(new Uri(url), form);
}
// GET
else
{
url = generateGetUrl(url, paramList);
response = await httpClient.GetAsync(new Uri(url));
}
return await response.Content.ReadAsStringAsync();
}
catch (Exception) { }
finally
{
if (httpClient != null)
{
httpClient.Dispose();
httpClient = null;
}
}
return null;
}
private static string generateGetUrl(string url, List<Parameter> paramList)
{
if(paramList == null || paramList.Count <= 0)
{
return url;
}
StringBuilder sb = new StringBuilder();
foreach (Parameter item in this.ParamList)
{
if (item == null || string.IsNullOrWhiteSpace(item.key) || string.IsNullOrWhiteSpace(item.value))
{
continue;
}
if (sb.Length > 0)
{
sb.Append("&");
}
sb.Append(string.Format("{0}={1}", item.key, System.Net.WebUtility.UrlEncode(item.value)));
}
return url + (url.IndexOf("?") == -1 ? "?" : "&") + sb.ToString();
}
private static MultipartFormDataContent getPostForm(List<Parameter> paramList)
{
MultipartFormDataContent form = new MultipartFormDataContent();
if (paramList != null)
{
foreach (var param in paramList)
{
if (!string.IsNullOrWhiteSpace(param.key))
{
form.Add(new StringContent(param.value, UTF8Encoding.UTF8), param.key);
}
}
}
return form;
}
#3. 處理Cookie,async
一般狀況下咱們須要保持client與server之間的session,server端是經過cookie來識別一個client與另一個client的。ide
咱們使用上面HttpClient的第2個構造函數,經過MessageProcessingHandler和CookieContainer來每次請求前,把cookie添加到request的header中。函數
public class CookieHandler : MessageProcessingHandler
{
static CookieHandler()
{
CookieContainer = new CookieContainer();
}
public static CookieContainer CookieContainer
{
get;
set;
}
public CookieHandler() : base(new CookieHttpClientHandler())
{
}
protected override HttpRequestMessage ProcessRequest(HttpRequestMessage request, System.Threading.CancellationToken cancellationToken)
{
return request;
}
protected override HttpResponseMessage ProcessResponse(HttpResponseMessage response, System.Threading.CancellationToken cancellationToken)
{
Uri httpsUri = new Uri("https://" + response.RequestMessage.RequestUri.Host);
var cookieCollection = CookieContainer.GetCookies(httpsUri);
foreach (Cookie cookie in cookieCollection)
{
cookie.Secure = false;
}
return response;
}
}
class CookieHttpClientHandler : HttpClientHandler
{
public CookieHttpClientHandler()
{
CookieContainer = CookieHandler.CookieContainer;
}
}
使用方式跟前面POST/GET代碼惟一不一樣的是:在構造HttpClient對象時,傳入CookieHandler:
var httpClient = new System.Net.Http.HttpClient(new CookieHandler());
2, 文件下載
#1 HttpClient提供了字節流的方式來讀取文件,但我測試發現,下載是成功了,但文件常常出現缺乏字節的狀況。不清楚是怎麼回事。
//
// 摘要:
// 將 GET 請求發送到指定 URI 並在異步操做中以字節數組的形式返回響應正文。
//
// 參數:
// requestUri:
// 請求發送到的 URI。
//
// 返回結果:
// 返回 System.Threading.Tasks.Task<TResult>。 表示異步操做的任務對象。
//
// 異常:
// System.ArgumentNullException:
// requestUri 爲 null。
public Task<byte[]> GetByteArrayAsync(string requestUri);
//
// 摘要:
// 將 GET 請求發送到指定 URI 並在異步操做中以字節數組的形式返回響應正文。
//
// 參數:
// requestUri:
// 請求發送到的 URI。
//
// 返回結果:
// 返回 System.Threading.Tasks.Task<TResult>。 表示異步操做的任務對象。
//
// 異常:
// System.ArgumentNullException:
// requestUri 爲 null。
public Task<byte[]> GetByteArrayAsync(Uri requestUri);
//
// 摘要:
// 將 GET 請求發送到指定 URI 並在異步操做中以流的形式返回響應正文。
//
// 參數:
// requestUri:
// 請求發送到的 URI。
//
// 返回結果:
// 返回 System.Threading.Tasks.Task<TResult>。 表示異步操做的任務對象。
//
// 異常:
// System.ArgumentNullException:
// requestUri 爲 null。
public Task<System.IO.Stream> GetStreamAsync(string requestUri);
//
// 摘要:
// 將 GET 請求發送到指定 URI 並在異步操做中以流的形式返回響應正文。
//
// 參數:
// requestUri:
// 請求發送到的 URI。
//
// 返回結果:
// 返回 System.Threading.Tasks.Task<TResult>。 表示異步操做的任務對象。
//
// 異常:
// System.ArgumentNullException:
// requestUri 爲 null。
public Task<System.IO.Stream> GetStreamAsync(Uri requestUri);
#2. BackgroundDownloader
Win 8提供了BackgroundDownloader能夠用於在後臺下載文件,它也能夠調用setRequestHeader向請求中添加header信息 (與上面的CookieHandler結合使用,能夠處理那些須要登錄才能下載文件的狀況),下面演示了普通的文件下載:
public async static Task<IAsyncOperation<StorageFile>> DownloadAsync(string url)
{
string fileName = url.Substring(url.LastIndexOf("/") + 1).Trim();
var option = Windows.Storage.CreationCollisionOption.ReplaceExisting;
StorageFile destinationFile = await Windows.Storage.ApplicationData.Current.LocalFolder.CreateFileAsync(fileName, option);
BackgroundDownloader downloader = new BackgroundDownloader();
DownloadOperation download = downloader.CreateDownload(new Uri(url), destinationFile);
await download.StartAsync().AsTask();
ResponseInformation response = download.GetResponseInformation();
if(response.StatusCode == 200)
{
DownloadHelper.addDownloadFileSuccess(fileName);
return DownloadHelper.getDownloadFileAsync(fileName);
}
return null;
}