閱讀897 返回首頁    go 技術社區[雲棲]


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

  上一篇:go Linq多表操作中事務的應用
  下一篇:go 怎麼在網站中插入天氣預報