分類  >  Web前端 >

公布WebQQ Client API庫1.0.0正式版

tags:    時間:2013-12-10 08:18:59
發布WebQQ Client API庫1.0.0正式版

最近在研發一個JIRA的插件,具體場景如下:

當測試人員提交一個問題時,需要通過QQ通知到開發人員,並且當問題屬於SIT測試BUG時,需要自動的打開SVN上對應主幹源代碼的寫許可權。當開發人員修復並關閉問題時,需要自動的關閉SVN上對應主幹源代碼的寫許可權。

基本實現思路如下:

  • 開發一個JIRA插件,基於ActiveMQ客戶端,並監聽JIRA的內部事件,如果是觸發提交問題的事件,就將該事件發布到MQ主題中;
  • 開發一個伺服器應用程序,訂閱MQ上由JIRA插件發布的事件消息,並進行對應的處理,例如發送QQ消息或是修改SVN許可權等。

實際上實現JIRA插件這一端的程序並不困難,關鍵是查閱JIRA SDK相關手冊,基本上沒什麼難度,下一篇文章,我們就來看看如何實現這個JIRA插件。這篇文章主要是關注如何實現與QQ的通訊,著實花費了不少心思。通過Google,發現目前網上大部分是基於WebQQ實現的,然後下載了一個什麼iQQ的實現代碼,沒什麼設計思想,基本上就是代碼的堆疊,不過可讀性還算好,基本能看懂,於是乎就有了想搞一個WebQQ客戶端API庫的衝動,方便今後的使用和擴展。經過幾天的整理和重構終於把WebQQ核心部分抽出來並形成一個API庫,以下為API介面定義:

/**  * WebQQ客戶端介面  * @author Administrator  * @version $Id: WebQQClient.java, v 0.1 2013-1-21 下午2:58:32 Administrator Exp $  */ public interface WebQQClient {     /**      * QQ登錄      * <blockquote>      * QQ完成登錄需要經過三次服務調用:      * <ol>      * <li>檢查QQ賬戶,是否需要驗證碼輸入;      * <li>正式登錄;      * <li>渠道登錄;      * </ol>      * </blockquote>      * @param member 需要提供QQ號碼和登錄密碼      * @return true 登錄成功 false 登錄失敗      */     boolean login(Member member);      /**      * 載入QQ好友詳情      * <blockquote>      * 前置條件: 必須已經成功登錄      * </blockquote>      * @param account 需要載入的好友QQ號碼(QQ系統內部還有一個uin標識)      * @return QQ會員詳情      */     Member loadFriend(String account);      /**      * 載入QQ好友的個性化簽名      * <blockquote>      * 前置條件: 必須已經成功登錄      * </blockquote>      * @param account 需要載入的好友QQ號碼(QQ系統內部還有一個uin標識)      * @return      */     Member loadFriendSignature(String account);      /**      * 載入QQ好友的等級      * <blockquote>      * 前置條件: 必須已經成功登錄      * </blockquote>      * @param account 需要載入的好友QQ號碼(QQ系統內部還有一個uin標識)      * @return      */     Member loadFriendLevel(String account);      /**      * 改變當前已登錄QQ會員的狀態      * <blockquote>      * 前置條件: 必須已經成功登錄      * </blockquote>      * @param newStatus 當前的新狀態      */     void changeStatus(Status newStatus);      /**      * 向指定的QQ好友發送消息      * <blockquote>      * 前置條件:       * <ol>      * <li>必須已經成功登錄;      * <li>已經成功載入了好友列表,因為發送QQ消息需要好友的uin欄位(一個內部的標識,每次登錄該欄位值都不一樣),而非QQ號碼;      * <li>已經成功啟動QQ心跳檢測任務,否則無法發送QQ消息;      * </ol>      * </blockquote>      * @param account 發送消息的好友的QQ號碼      * @param message 發送的消息內容      * @return true 發送成功 false 發送失敗      */     boolean sendMessageToFriend(String account, String message);      /**      * 向指定的QQ群發送消息      * <blockquote>      * 前置條件:       * <ol>      * <li>必須已經成功登錄;      * <li>已經成功載入了好友群列表,因為發送QQ消息需要好友群的uin欄位(一個內部的標識,每次登錄該欄位值都不一樣),而非群號碼;      * <li>已經成功啟動QQ心跳檢測任務,否則無法發送QQ消息;      * </ol>      * </blockquote>      * @param account 發送消息的QQ群號      * @param message 發送的消息內容      * @return      */     boolean sendMessageToGroup(String account, String message);      /**      * QQ登出      * <blockquote>      * 前置條件: 必須已經成功登錄      * </blockquote>      * @return true 登出成功 false 登出失敗      */     boolean logout();      /**      * 查詢好友列表      * <blockquote>      * 前置條件: 必須已經成功登錄      * </blockquote>      * @return 好友列表      */     List<Member> findFriends();      /**      * 查詢在線的好友列表      * <blockquote>      * 前置條件: 必須已經成功登錄      * </blockquote>      * @return 在線好友列表      */     List<Member> findOnlineFriends();      /**      * 查詢QQ群列表      * <blockquote>      * 前置條件: 必須已經成功登錄      * </blockquote>      * @return      */     List<Group> findGroups(); }
該API庫的主要功能有:

  • QQ登錄;
  • 查詢QQ好友列表;
  • 查詢QQ群列表;
  • 查詢在線QQ好友列表;
  • 載入QQ好友詳情;
  • 載入QQ好友個性化簽名;
  • 載入QQ好友等級;
  • 更變當前登錄狀態;
  • 向QQ好友發送消息;
  • 向好友QQ群發送群消息;
  • QQ心跳檢查線程任務,用於保持在線狀態;
  • 提供QQ事件監聽器介面,用於擴展QQ消息和QQ群消息的接收處理;
  • QQ登出;

當然因為是一個API庫,所以和UI相關的功能基本上都沒有實現,有待感興趣的同學繼續完善。

該API庫的依賴庫如下:

  • Apache Commons Lang
  • Apache Commons Collections
  • Apache Commons Beanutils
  • Apache Commons Logging
  • Spring Framework
  • Apache Log4j
  • JSON
  • Storevm Commons

如果是使用maven管理依賴的話,那就簡單了,可以看我項目源代碼中提供的pom.xml文件。

以下介紹使用的方法,由於該API是依賴Spring框架的,所以要做的就是配置幾個Bean,以下假設您使用Maven工具以及Spring進行開發:

1. 在pom.xml中配置如下依賴:

<dependency>     <groupId>org.storevm</groupId>     <artifactId>webqq-client</artifactId>     <version>1.0.0</version> </dependency>
當然,這個Jar在Maven中央庫是沒有的,所以需要在pom.xml中添加上我的Maven私有庫地址:

<repositories>     <repository>         <id>StoreVM-repo</id> 	<name>StoreVM Maven Repository</name> 	<url>http://mvn.storevm.org:8081/mvn/content/groups/public</url> 	<releases> 	    <enabled>true</enabled> 	</releases> 	<snapshots> 	    <enabled>true</enabled> 	</snapshots>     </repository> </repositories>
OK,最後執行

mvn eclipse:eclipse

回到Eclipse上,刷新一下自己的項目,就能看到新加入的庫了。

2. 接著在您項目的Spring配置文件中定義如下的 Bean:

<bean id="webQQClientContainer" class="org.storevm.im.WebQQClientContainer">     <property name="account" value="您的QQ號碼"/>     <property name="password" value="您的QQ登錄密碼"/> </bean>
WebQQClientContainer類實現了InitializingBean和DisposableBean介面,所以在Bean載入的時候會執行QQ登錄相關的操作,而在Bean卸載的時候會執行了QQ登出的操作,部分源代碼如下:

    /**       * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()      */     @Override     public void afterPropertiesSet() throws Exception {         Member member = new Member();         member.getAccount().setAccount(qqNumber);         member.getAccount().setPassword(qqPassword);         member.setStatus(Status.ONLINE);         //登錄WebQQ,登錄之後就可以發送消息了         boolean success = webQQClient.login(member);         if (success) {             //如果登錄成功,則載入在線好友列表和QQ群列表             List<Member> olineFriends = webQQClient.findOnlineFriends();             List<Group> groups = webQQClient.findGroups();              //啟動心跳檢測任務             heartbeatTaskExecutor.startup();             LogUtils.info(LOGGER, "啟動WebQQ客戶端容器完成. 在線好友數=[{0}], QQ群數=[{1}]", olineFriends.size(),                 groups.size());         } else {             LogUtils.warn(LOGGER, "啟動WebQQ客戶端失敗, account={0}", qqNumber);         }     } 

    /**       * @see org.springframework.beans.factory.DisposableBean#destroy()      */     @Override     public void destroy() throws Exception {         //當Bean銷毀時,關閉WebQQ客戶端管理容器         heartbeatTaskExecutor.shutdown();         boolean success = webQQClient.logout();         if (success) {             LogUtils.warn(LOGGER, "關閉WebQQ客戶端完成, account={0}", qqNumber);         } else {             LogUtils.warn(LOGGER, "關閉WebQQ客戶端失敗, account={0}", qqNumber);         }     }

經過以上的配置,您就可以在程序運行的任何時刻調用WebQQClient介面發送QQ消息了。這裡需要注意的是,Jar包中已經定義了相關bean的配置,無需在你自己的項目中重複定義Bean,不過需要通過設置classpath*:applicationContext.xml的方式來載入Jar包中的Spring配置文件。

如果您的應用程序是Web程序,我也寫了一個ServletContextListener介面用於在Web容器啟動時初始化WebQQ客戶端:

1. 在web.xml中添加如下配置:

<context-param>     <param-name>account</param-name>     <param-value>您的QQ號碼</param-value> </context-param> <context-param>     <param-name>password</param-name>     <param-value>您的QQ登錄密碼</param-value> </context-param>
<listener>     <listener-class>org.storevm.im.WebQQClinetListener</listener-class> </listener>
通過上述配置,當web容器啟動時會執行QQ登錄操作,然後您就可以在應用程序的運行過程中發送QQ消息,當然在容器關閉時會執行QQ登出的操作。
關於QQ消息的接收,我採用事件監聽器的方式進行實現,您需要做的就是實現WebQQEventListener介面以及InitializingBean和DisposableBean介面,以下為一個簡單的事件監聽器實現代碼:

/**  * 接收QQ消息的監聽器實現  * @author Administrator  * @version $Id: ReceiveFriendMessageListener.java, v 0.1 2013-1-24 下午3:28:15 Administrator Exp $  */ public class ReceiveMessageListener implements WebQQEventListener, InitializingBean, DisposableBean {     /* logger */     private static final Logger LOGGER = Logger.getLogger(ReceiveMessageListener.class);      /* 事件發布器 */     private WebQQEventPublisher eventPublisher;      /**      * 構造函數      */     public ReceiveMessageListener() {     }      /**       * @see org.springframework.beans.factory.DisposableBean#destroy()      */     @Override     public void destroy() throws Exception {         eventPublisher.unregister(this); //註銷     }      /**       * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet()      */     @Override     public void afterPropertiesSet() throws Exception {         eventPublisher.register(this); //註冊監聽器     }      /**       * @see org.storevm.im.core.event.WebQQEventListener#onWebQQEvent(org.storevm.im.core.event.WebQQEvent)      */     @Override     public void onWebQQEvent(WebQQEvent event) {         LogUtils.info(LOGGER, "接收到QQ事件, event.code={0}, body={1}", event.getEventCode(),             event.getBody());     }      /**      * Setter method for property <tt>eventPublisher</tt>.      *       * @param eventPublisher value to be assigned to property eventPublisher      */     public void setEventPublisher(WebQQEventPublisher eventPublisher) {         this.eventPublisher = eventPublisher;     }  }
以上代碼的關鍵點是註冊監聽器和onWebQQEvent方法的實現。你也可以註冊多個監聽器,用於監聽多個事件。更多的單元測試請下載源代碼查看。

以下提供SVN源代碼地址:

http://svn.storevm.org/svn/webqqclient/trunk

用戶名和密碼均為:reader

項目使用Maven進行管理,關於maven的使用請自行參考網上其他文章。最後希望對此有興趣的同學可以相互交流經驗技術。

推薦閱讀文章

Bookmark the permalink ,來源:互聯網