897
技術社區[雲棲]
java之httpclient點點補充-登錄問題
本來有點不太想寫這篇文章,原因是寫了這個,就感覺WEB應用怎麼都可以自己寫代碼訪問內部的資源信息!不過出於技術本身的我還是考慮些點點東西,而且即使我不寫,這玩意也有,嗬嗬,前麵一篇文章我提及到雙方要約定token來進行認證交互等等,如果你想訪問某個網站內部的資源,而且是需要登錄的,但是又想通過本地程序直接蹦進去,怎麼蹦呢?
辦法不是沒有,其實httpclient就是模擬一個瀏覽器的功能,而登錄的動作其實就是獲取到你的cookie,而httpclient本身有記錄cookie的功能,所以這並不難。
也就是說,你要用httpclient來模擬一個網站的登錄,然後後續的操作;那麼你隻需要到那個網站的登錄頁麵中找到用戶名和密碼的標簽的name值,以及其action的目標地址,將其在本地開始進行模擬,標簽,並類似於上一篇文章中編寫用戶名和密碼並向action的目標地址發起的post操作(注意這裏的POST應該是絕對路徑,而不是頁麵看到的相對路徑),此時你就能獲取到你的cookie了;
那麼登錄OK了,cookie獲取到了,如何保存cookie呢?其實你根本不用保存,因為httpclient已經幫你保存了,接下來所有的動作,隻需要你使用同一個httpclient對象,它們的cookie就是一致的,可以通過同一個httpclient對象發起多次POST或GET請求,這個時候內部想要請求什麼就請求什麼了。
貌似本文就結束了,要這麼簡單,我也不會專門抽出來寫了,其實上述方法隻能適合於一般的普通網站,如果網站的認證方法是https的,也就是你看到它的登錄界麵是https開頭的,那就不行了因為協議不一樣了,不過也是有辦法的,這也是本文需要闡述的重點,要做這個工作,httpcleint請換成4以上的版本,對應到的包有:commons-httpclient-4.1.3.jar以及httpclient-4.1.2.jar兩個包不是一樣的內容,在這裏這兩個包都需要(注意一下代碼為非U盾認證方式,U盾認證需要其他的代碼來支持)。
加上了這兩個包後,在程序開始部分import的內容應該包含:
import org.apache.http.HttpEntity; import org.apache.http.HttpResponse; import org.apache.http.NameValuePair; import org.apache.http.client.entity.UrlEncodedFormEntity; import org.apache.http.client.methods.HttpGet; import org.apache.http.client.methods.HttpPost; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.impl.client.DefaultHttpClient; import org.apache.http.message.BasicNameValuePair; import org.apache.http.protocol.HTTP; import org.apache.http.util.EntityUtils; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.List; 如果你有什麼包引入不進來,說明你找的包還不對。 public class HttpsTest1 { /** * SSL部分的處理 * @param httpClient * @throws NoSuchAlgorithmException * @throws KeyManagementException */ private static void securityProcess(DefaultHttpClient httpClient) throws NoSuchAlgorithmException, KeyManagementException { TrustManager easyTrustManager = new X509TrustManager() { public void checkClientTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) throws java.security.cert.CertificateException {} public void checkServerTrusted(java.security.cert.X509Certificate[] x509Certificates, String s) throws java.security.cert.CertificateException {} public java.security.cert.X509Certificate[] getAcceptedIssuers() { return new java.security.cert.X509Certificate[0]; } }; SSLContext sslcontext = SSLContext.getInstance("TLS"); sslcontext.init(null, new TrustManager[]{easyTrustManager}, null); SSLSocketFactory sf = new SSLSocketFactory(sslcontext); Scheme sch = new Scheme("https", 443, sf); httpClient.getConnectionManager().getSchemeRegistry().register(sch); } /** * 處理登錄 * @param httpClient * @throws UnsupportedEncodingException * @throws IOException * @throws ClientProtocolException */ private static void login(DefaultHttpClient httpClient) throws UnsupportedEncodingException, IOException,ClientProtocolException { HttpPost httppost = new HttpPost("https://www.xxx.xxx.com/login/");//這是用戶名和密碼提交的目標路徑 List<NameValuePair> params=new ArrayList<NameValuePair>(); params.add(new BasicNameValuePair("id",MyUserInfo.USER_NAME));//寫入用戶名 params.add(new BasicNameValuePair("pass_word",MyUserInfo.PASSWORD));//寫入密碼 httppost.setEntity(new UrlEncodedFormEntity(params,HTTP.UTF_8)); HttpResponse response = httpClient.execute(httppost); HttpEntity entity = response.getEntity(); String content = EntityUtils.toString(entity); System.out.println(content); } public static void main(String[] args) throws Exception { DefaultHttpClient httpClient = new DefaultHttpClient(); try { securityProcess(httpClient); login(httpClient); //以下是你要請求其他的URL HttpGet get = new HttpGet("https://www.xxx.xxx.com/xxx/xxx"); HttpResponse response2 = httpClient.execute(get); System.out.println(EntityUtils.toString(response2.getEntity())); }finally { httpClient.getConnectionManager().shutdown(); } } }
OK。代碼細節上我不想多說,不過這段代碼去請求一個https的登錄是絕對沒有問題的,可以將相應的URL換成自己係統的,再試一試!雖然是這個功能,不過,我個人還是不建議這樣做,這樣做太張揚了,這裏僅僅為簡單探討下,可以用它寫點程序實現遠程係統的本地自動化處理步驟。
另外驗證碼需要一些解析程序,相對較為複雜,而且可能解析會有問題,對這類問題我也不想研究太多,嗬嗬,本文說提及的這個程序也和驗證碼無關。
最後更新:2017-04-02 06:52:24