相对于httpurlconnection ,httpclient更加丰富,也更加强大,其中apache有两个项目都是httpclient,一个是commonts包下的,这个是通用的,更专业的是org.apache.http.包下的,所以我一般用后者;
httpclient可以处理长连接,保存会话,重连接,以及请求过滤器,连接重用等等...
下面是测试代码(全部总结来自官方文档,以及翻译)
须要下载核心包:httpclient-4.3.4.jar ,也可在官网下载:http://hc.apache.org/downloads.cgi
/** * HTTP认证: * * HTTPclient支持http标准认证,也支持其他认证,如NTLM和SPNEGO。 */ private static void test17(){ //最简单的明文用户名 密码认证。 UsernamePasswordCredentials creds = new UsernamePasswordCredentials("user", "pwd"); System.out.println(creds.getUserPrincipal().getName()); System.out.println(creds.getPassword()); /** * NTCredentials是微软的windows系统使用的一种凭据,包含username、password,还包括一系列其他的属性, * 比如用户所在的域名。在Microsoft Windows的网络环境中,同一个用户可以属于不同的域,所以他也就有不同的凭据。 * workstation:本机的计算机名 */ NTCredentials ntcreds = new NTCredentials("user", "pwd", "workstation", "domain"); System.out.println(ntcreds.getUserPrincipal().getName());//输出 DOMAIN/user System.out.println(ntcreds.getPassword()); } /** * 凭证提供者(CredentialsProvider)内含一套特定的凭证,须要哪种凭证时,CredentialsProvider就能获得对应的凭证。 * 获取凭证的时候,可以模糊的指定主机名、端口号、realm和认证方案。 * CredentialsProvider会筛选出一个最佳匹配方案。 */ private static void test18() { CredentialsProvider credsProvider = new BasicCredentialsProvider(); credsProvider.setCredentials(new AuthScope("somehost",AuthScope.ANY_PORT), new UsernamePasswordCredentials("u1", "p1")); credsProvider.setCredentials(new AuthScope("somehost", 8080), new UsernamePasswordCredentials("u2", "p2")); credsProvider.setCredentials(new AuthScope("otherhost", 8080,AuthScope.ANY_REALM, "ntlm"), new UsernamePasswordCredentials("u3", "p3")); System.out.println(credsProvider.getCredentials(new AuthScope( "somehost", 80, "realm", "basic"))); System.out.println(credsProvider.getCredentials(new AuthScope( "somehost", 8080, "realm", "basic"))); System.out.println(credsProvider.getCredentials(new AuthScope( "otherhost", 8080, "realm", "basic"))); System.out.println(credsProvider.getCredentials(new AuthScope( "otherhost", 8080, null, "ntlm"))); /** * 输出: * [principal: u1] [principal: u2] null [principal: u3] */ } private static void test19() throws ClientProtocolException, IOException { // CloseableHttpClient httpclient = HttpClients.createDefault(); // HttpClientContext context = HttpClientContext.create(); // // HttpHost targetHost = new HttpHost("webservice.webxml.com.cn", 80, "http"); // // //认证提供者 // CredentialsProvider credsProvider = new BasicCredentialsProvider(); // credsProvider.setCredentials(new AuthScope(targetHost.getHostName(),targetHost.getPort()), // new UsernamePasswordCredentials("root", "root")); // // //基础认证缓存 // AuthCache authCache = new BasicAuthCache(); // // context.setCredentialsProvider(credsProvider); // context.setAuthCache(authCache); // // HttpGet httpget = new HttpGet("/WebServices/MobileCodeWS.asmx/getDatabaseInfo"); // // CloseableHttpResponse response = httpclient.execute(targetHost,httpget, context); // // AuthState proxyAuthState = context.getProxyAuthState(); // // System.out.println("Proxy auth state: " + proxyAuthState.getState()); // System.out.println("Proxy auth scheme: "+ proxyAuthState.getAuthScheme()); // System.out.println("Proxy auth credentials: "+ proxyAuthState.getCredentials()); // AuthState targetAuthState = context.getTargetAuthState(); // System.out.println("Target auth state: " + targetAuthState.getState()); // System.out.println("Target auth scheme: "+ targetAuthState.getAuthScheme()); // System.out.println("Target auth credentials: "+ targetAuthState.getCredentials()); /** * Proxy auth state: UNCHALLENGED Proxy auth scheme: null Proxy auth credentials: null Target auth state: UNCHALLENGED Target auth scheme: null Target auth credentials: null */ } /** * HttpClientContext 设置抢先认证 和 认证提供者: * * 在HTTP中,基本认证是一种用来允许Web浏览器或其他客户端程序在请求时提供以用户名和口令形式的凭证。 * * 一般http basic认证,首先登录服务器, 然后服务器会返回401码让客户端输入用户名和密码,客户端把用户名密码进行BASE64加密, * * 最后把加密后的用户名和密码发送给服务器进行验证。 * * 抢先验证则省略了前几部,直接发送BASE64位密文,进行验证,但存在风险,慎用! */ private static void test20() throws ClientProtocolException, IOException { HttpClientContext context = HttpClientContext.create(); CloseableHttpClient httpclient = HttpClients.createDefault(); //配置主机 , 端口可随意填写 HttpHost targetHost = new HttpHost("webservice.webxml.com.cn", 80, "http"); //认证提供者 CredentialsProvider credsProvider = new BasicCredentialsProvider(); credsProvider.setCredentials( new AuthScope(targetHost.getHostName(),targetHost.getPort()), new UsernamePasswordCredentials("username", "password")); AuthCache authCache = new BasicAuthCache(); BasicScheme basicAuth = new BasicScheme(); authCache.put(targetHost, basicAuth); //提前填充认证信息缓存到上下文中,这样,以这个上下文执行的方法,就会使用抢先认证。可能会出错 context.setAuthCache(authCache); context.setCredentialsProvider(credsProvider); HttpGet httpget = new HttpGet("/WebServices/MobileCodeWS.asmx/getDatabaseInfo"); CloseableHttpResponse response = httpclient.execute(targetHost,httpget, context); try { HttpEntity entity = response.getEntity(); String result = EntityUtils.toString(entity); System.out.println(result); } finally { response.close(); } } /** * NTLM连接认证: * * windows提供的一套安全、复杂的、有状态的协议。 * * 相比Basic和Digest认证,NTLM认证要明显需要更多的计算开销,性能影响也比较大。 * * 也就是说,NTLM连接一旦建立,用户的身份就会在其整个生命周期和它相关联。 */ private static void test21() throws ClientProtocolException, IOException { // 确保使用同一个上下文 HttpClientContext context = HttpClientContext.create(); CloseableHttpClient httpclient = HttpClients.createDefault(); CredentialsProvider credsProvider = new BasicCredentialsProvider(); //构建详细nt认证信息:NTCredentials 参数1:用户名 2:密码 3:本机名 3:domain域 credsProvider.setCredentials(new AuthScope("somehost",AuthScope.ANY_PORT) , new NTCredentials("username", "password", "myworkstation", "domain")); context.setCredentialsProvider(credsProvider); HttpHost target = new HttpHost("somehost", 80, "http"); HttpGet httpget = new HttpGet("/"); CloseableHttpResponse response1 = httpclient.execute(target, httpget, context); try { HttpEntity entity1 = response1.getEntity(); System.out.println(EntityUtils.toString(entity1,"GB2312")); } finally { response1.close(); } HttpPost httppost = new HttpPost("/"); httppost.setEntity(new StringEntity("lots and lots of data")); CloseableHttpResponse response2 = httpclient.execute(target, httppost, context); try { HttpEntity entity2 = response2.getEntity(); } finally { response2.close(); } }
时间: 2024-11-11 22:49:36