熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> Java編程 >> Java核心技術 >> 正文

利用httpclient模擬站點的登錄發帖回復

2013-11-23 18:52:47  來源: Java核心技術 

  HttpClient 是 Apache Jakarta Common 下的子項目可以用來提供支持 HTTP 協議的客戶端編程工具包模擬浏覽器的行為它提供了很多的方法來簡化網絡的訪問雖然大部分的功能可以使用較底層的 HttpURLConnection 來實現例如

  實現了所有 HTTP 的方法( GETPOST 等)

  支持 HTTPS 協議

  支持代理服務器

  自動維護 Cookies 等

  我們知道 http 協議是面向無連接的要維持會話現在基本上都是采用基於 Cookies 的方式( Session 機制也是通過 Cookies 實現的)所以 HttpClient 的自動維護 Cookies 的方式對我們的登錄發帖回復非常有用(一般網站都需要先登錄再發帖回復)

  下面的 例子都是采用 commons 包來實現的(雖然 commons 已經發布但是代碼發生了較大的重構調用方式也發生了很大的改變)

  下載 jar 包的路徑為

  由於 httpclient 使用了 Apache Jakarta common 下的子項目 logging 和 codec 所以也需要在 下載這兩個包

  commonsloggingjar

  commonscodecjar

  為了更好地理解代碼設計的 UML 類圖如下

  方法調用的時序圖如下

  其中 BrowserContext 類代表浏覽器上下文對象維護 HttpClient 鏈接和 Cookies KaixinSitePost 是負責實現開心網的具體登錄發帖回復邏輯的類

  BrowserContext 的代碼如下

     /** */ /**

    *  Copyright (C):

    *   @author  陳新漢

    *  Aug :: PM

     */

  

     /** */ /**

    * 浏覽器進程上下文

     */

    public   class  BrowserContext

      {

        private  HttpClient client;  // 注意每個站點和每個用戶對應一個單獨的BrowserContext對象

         private  Cookie[] cookies = new  Cookie[ ];  // 維護Cookies

         private  Proxyips proxyip = null ;  // 當前的代理IP

         private  Siteusers user = null ;  // 當前的登錄用戶

  

         public  Cookie[] getCookies()   {

            return  cookies;

       }

  

         public   void  setCookies(Cookie[] cookies)   {

            okies  =  cookies;

       }

  

         public   void  addCookie(Cookie c)  {

             if (cookies != null   &&  cookieslength > )  {

               Cookie[] others = new  Cookie[cookieslength + ];

               Systemarraycopy(cookies  others  cookieslength);

               others[otherslength ] = c;

               cookies = others;

            } else  {

               cookies = new  Cookie[ ];

               cookies[ ] = c;

           }

       }

  

         public  Proxyips getProxyip()   {

            return  proxyip;

       }

  

         public   void  setProxyip(Proxyips proxyip)   {

            this proxyip  =  proxyip;

             if ( this proxyip != null )  {

               clientgetHostConfiguration()setProxy(proxyipgetIp()proxyipgetPort());

               clientgetParams()setAuthenticationPreemptive( true );

                // 如果代理需要密碼驗證這裡設置用戶名密碼

                // clientgetState()setProxyCredentials(AuthScopeANY new UsernamePasswordCredentials());

            }

       }

  

         public  HttpClient getClient()   {

            return  client;

       }

  

         public  Siteusers getUser()   {

            return  user;

       }

  

         public   void  setUser(Siteusers user)   {

            this user  =  user;

       }

  

         private  BrowserContext(Site site)   {

            super ();

           Protocol myhttps  =   new  Protocol( https   new  MySecureProtocolSocketFactory()  );

           ProtocolregisterProtocol( https myhttps);

           client  =   new  HttpClient();

           clientgetParams()setCookiePolicy(CookiePolicyBROWSER_COMPATIBILITY);

           HttpConnectionManagerParams managerParams  =  clientgetHttpConnectionManager()getParams();

            //  設置連接超時時間(單位毫秒)

            // managerParamssetConnectionTimeout();

            //  設置讀數據超時時間(單位毫秒)

            // managerParamssetSoTimeout();

            initForSiteVisit(sitegetSite()sitegetPort()sitegetCharset());

       }

  

         public  BrowserContext(Site siteProxyips proxyip)   {

            this (site);

            this setProxyip(proxyip);

       }

  

         private   void  initForSiteVisit(String siteurl int  portString charset)  {

           clientgetHostConfiguration()setHost(siteurl port http );

            // 解決中文亂碼問題和指定網站的頁面編碼一致

            clientgetParams()setParameter(HttpMethodParamsHTTP_CONTENT_CHARSET charset);

       }

  

            //  查看cookie信息

         public   void  printCookies()

          {

           Systemoutprintln( Cookie );

             if (cookies != null )  {

                 for (Cookie c:cookies)  {

                   Systemoutprintln(cgetName() + : + cgetValue());

               }

            } else  {

               Systemoutprintln( 沒有設置Cookies );

           }

           Systemoutprintln( Cookie );

       }

  

        public   void  setCommonMethodRequestHeaders(HttpMethodBase method)

          {

           methodsetRequestHeader( Accept   */* );

            // methodsetRequestHeader(AcceptLanguage zhcn);

            // methodsetRequestHeader(AcceptEncoding gzipdeflate);

            methodsetRequestHeader( UserAgent   Mozilla/ (compatible; MSIE ; Windows NT ;) );

            // 設置非常重要

            methodsetRequestHeader( Connection   KeepAlive );

       }

  

        public  String redirectToURL(String url)  throws  IOException

          {

             if (url != null )  {

                 try  {

                   Systemoutprintln( 頁面重定向到 + url);

                   String responseString = this doCommonVisitWithURL(url);

                    // Systemoutprintln(responseString);

                     return  responseString;

                } catch (IOException e)  {

                   Systemoutprintln( 重定向 + url + 出錯 );

               }

            } else  {

               Systemoutprintln( redirect url is null );

           }

            return   null ;

       }

  

         public  String doCommonVisitWithURL(String url)  throws  IOException   {

           GetMethod get  =   new  GetMethod(url);

            return   this doGet(get);

       }

  

        public  String doPost(ExpectContinueMethod post)  throws  IOException

          {

            if (post == null )

                return   null ;

            try

              {

                 if (getCookies() != null )  {

                    // printCookies();

                    clientgetState()addCookies(cookies);

                   postaddRequestHeader( Cookie getCookies()toString());

                    // Systemoutprintln(postgetRequestHeader(Cookie)getValue());

                }

               setCommonMethodRequestHeaders(post);

                int  statusCode  =  clientexecuteMethod(post);

               cookies = clientgetState()getCookies();

               Systemoutprintln(statusCode);

                // Systemoutprintln(postgetResponseHeader(Location));

                String responseString  =  postgetResponseBodyAsString();

               Systemoutprintln(responseString);

               printCookies();

               postreleaseConnection();

                 if  (statusCode  ==      ||  statusCode == )   {

                   redirectToURL(postgetResponseHeader( Location )getValue());

               }

                return  responseString;

           }

             finally    {

                if  (post  !=   null )

                   postreleaseConnection();

           }

       }

  

        public  String doGet(GetMethod get)  throws  IOException

          {

            if (get == null )

                return   null ;

             if (cookies != null )  {

                // printCookies();

                clientgetState()addCookies(cookies);

               getaddRequestHeader( Cookie cookiestoString());

           }

             try  {

               setCommonMethodRequestHeaders(get);

                int  statusCode  =  clientexecuteMethod(get);

               cookies = clientgetState()getCookies();   // 重新保存Cookies

                printCookies();

               Systemoutprintln(statusCode);

                 if (statusCode  ==      ||  statusCode == )  {

                   redirectToURL(getgetResponseHeader( Location )getValue());

               }

               String responseString  =  getgetResponseBodyAsString();

                // Systemoutprintln(responseString);

                 return  responseString;

           }

             finally  {

                if (get != null )

                   getreleaseConnection();

           }

       }

  

        public  String getRedirectURL(String content)

          {

            if (content != null   &&  contentindexOf( windowlocation=\ )!=){

                 int  begin = contentindexOf( windowlocation=\ );

                 int  end = contentindexOf( \ begin+);

                 return  contentsubstring(begin + end);

           }

            return   null ;

       }

   }

  KaixinSitePost類的代碼

  /** *//**

   *  Copyright (C):

   *  @author 陳新漢

   *  Aug :: AM

   */

  

  /** *//**

   * 模擬測試網站(不需要驗證碼)

   * 開心網()

   */

  public class KaixinSitePost implements ISitePost

  {

      private static final String LOGON_SITE = ;

      private static final int LOGON_PORT = ;

      private static final String CHARSET=UTF;

      private BrowserContext context=null;

  

  

      //單個用戶登錄

      public String login(Siteusers userinfo Proxyips ip)

      {

          if(userinfo!=null)

          {

              SiteLogin login=new SiteLogin(context);

              if(ip!=null)

                  logingetContext()setProxyip(ip);

              Map<StringString> params=new HashMap<StringString>();

              paramsput(ss );

              paramsput(loginregFrom index);

              paramsput(origURL );

              paramsput(email userinfogetUsername());

              paramsput(password userinfogetUserpwd());

              loginaddRequestParameters(params);

              return loginlogin(userinfo);

          }

          return null;

      }

  

      public List<Siteboards> parseBoard(Siteboards data) {

  

          return null;

      }

  

      public String post(Postinfos postinfoList<Siteboards> siteboards)

      {

          if(postinfo!=null && siteboards!=null){

              SitePost sport=new SitePost(context);

              contextgetClient()getHostConfiguration()setHost();

              Map<StringString> params=new HashMap<StringString>();

              paramsput(categoryId );

              paramsput(blogControl );

              paramsput(title postinfogetTitle());

              paramsput(bodypostinfogetContent());

              sportaddRequestParameters(params);

  

              for(Siteboards sb:siteboards){

                  sbsetPostUrl();

                  try{

                      sportpost(postinfo sb);

                  }catch(IOException e){

                      eprintStackTrace();

                  }

              }

          }

          return null;

      }

  

  

      public String reply(Postinfos postinfoList<Articleinfos> arts)

      {

  

          return null;

      }

  

      /** *//**

       * @param args

       */

      public static void main(String[] args)

      {

          try

          {

              Siteusers userinfo=new Siteusers();

              userinfosetUsername(xxxx);

              userinfosetUserpwd(xxxx);

              Proxyips ips = new Proxyips();

              ipssetIp();

              ipssetPort();

              KaixinSitePost sp=new KaixinSitePost();

              splogin(userinfoips);

              Postinfos post=new Postinfos();

              postsetContent(<p>lllllllllllllllllllllll</p>);

              postsetTitle(中文測試);

              List<Siteboards> siteboards=new ArrayList<Siteboards>();

              siteboardsadd(new Siteboards());

              siteboardsadd(new Siteboards());

              sppost(postsiteboards);

          }

          catch(Exception e){

              eprintStackTrace();

          }

      }

  }

  封裝登錄的類SiteLogin

  /** *//**

   *  Copyright (C):

   *  @author 陳新漢

   *  Aug :: PM

   */

  

  /** *//**

   * 站點登錄

   */

  public class SiteLogin extends AbstractMethodAdapter

  {

      private HttpMethodBase method;

      private boolean ispost=true;

      protected BrowserContext context; //當前的浏覽器進程上下文

  

      public BrowserContext getContext() {

          return context;

      }

  

      /** *//**

       * 構造函數

       * @param context

       * @param url

       * @param ispost 設置是否POST方式提交默認為POST

       */

      public SiteLogin(BrowserContext contextString urlboolean ispost) {

          super();

          ntext = context;

          thisispost=ispost;

          method = thisispost?new PostMethod(url):new GetMethod(url);

      }

  

      public SiteLogin(BrowserContext contextString url) {

          this(contexturltrue);

      }

  

      public String login(Siteusers user)

      {

          int statusCode=;

          if(thisispost && thishasRequestParameters()){

              ((PostMethod)method)setRequestBody(thisgetRequestParams());

          }

  

          if(thishasExtraRequestHeaders()){

              thisaddExtraRequestHeaders(methodthisgetExtraRequestHeaders());

          }

          contextsetCommonMethodRequestHeaders(method);

          try

          {

              if(contextgetCookies()!=null){

                  //printCookies();

                  contextgetClient()getState()addCookies(contextgetCookies());

                  methodaddRequestHeader(Cookie contextgetCookies()toString());

              }

              statusCode = contextgetClient()executeMethod(method);

              contextsetCookies(contextgetClient()getState()getCookies());

              String responseString = methodgetResponseBodyAsString();

              //Systemoutprintln(responseString);

              methodreleaseConnection();

              if(statusCode==HttpStatusSC_OK){

                  Systemoutprintln(登錄成功);

                  return responseString;

              }

              else if(statusCode== ||statusCode==){

                  Systemoutprintln(登錄成功頁面重定向);

                  String url=methodgetResponseHeader(Location)getValue();

                  return contextredirectToURL(url);

              }

              else{

                  Systemoutprintln(登錄失敗狀態碼+statusCode);

              }

          }catch(Exception e){

              eprintStackTrace();

          }finally{

              if(method!=null)

                  methodreleaseConnection();

          }

          return null;

      }

  }

  封裝站點發帖的類SitePost

  /** *//**

   *  Copyright (C):

   *  @author 陳新漢

   *  Aug :: PM

   */

  

  /** *//**

   * 站點發帖新帖

   */

  public class SitePost extends CommonSitePost

  {

  

      public SitePost(BrowserContext context) {

          super();

          ntext=context;

      }

  

      public String post(Postinfos postinfoSiteboards siteboard) throws IOException

      {

          if (postinfo != null && siteboard != null) {

              if (StringUtilsisNotEmpty(siteboardgetPostUrl())) {

                  PostMethod post = new PostMethod(siteboardgetPostUrl());

                  if(thishasRequestParameters()){

                      postsetRequestBody(thisgetRequestParams());

                  }

                  if(thishasExtraRequestHeaders()){

                      thisaddExtraRequestHeaders(postthisgetExtraRequestHeaders());

                  }

                  contextsetCommonMethodRequestHeaders(post);

                  ntextdoPost(post);

              }else{

                  Systemoutprintln(版面的新帖提交地址不能為空!);

              }

          }else{

              Systemoutprintln(帖子或者版面信息輸入都不能為空);

          }

          return null;

      }

  }


From:http://tw.wingwit.com/Article/program/Java/hx/201311/25911.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.