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