JAVA WEB項目與Discuz 論壇整合的詳細步驟完全版目前未有看到,最近遇到有人在問,想到這個整個不是一時半會也解釋不清楚。便把整個整合過程以及後續碰到的問題解決方案寫下,以供參考。
原理
Discuz 和 JAVA 對接需要一箇中間件,它就是 Ucenter。Comsenz(康盛)的 UCenter 當前在國內的單點登錄領域佔據絕對份額,其完整的產品線令 UCenter 成爲了賬號集成方面事實上的標準。基於 UCenter,可以將 Comsenz 旗下的 Discuz!(社區論壇系統)、SupeSite(門戶CMS系統)、X-Space(博客系統)從用戶資源層面進行無縫整合,使得賬號實現統一管理,在任何一個系統中進行註冊、登錄、註銷等操作時,該賬號在其他系統中的會話狀態也將同步更新,最終實現一號通的單點登錄模式。
使用 UCenter 進行同步操作,主要依託於 Ucenter Server 和 Ucenter Client之間的 api 接口進行通訊。要使得通訊成爲可能,首先要通過 Ucenter 管理所用應用(通過配置使得當前應用和 Ucenter 產生聯繫,也就是通訊成功)。其他應用通過掛接到 Ucenter 的接口上,從而使得某些數據可以進行同步操作。
整個分爲兩大部分:
1.整合部分(包括代碼嵌入、UCenter配置、方法調用)
2.問題部分(如何免激活登陸、中文登錄名亂碼問題等)
整合部分
首先,當然是進行項目整合。
開始這一部分的前提是你的論壇已經啓動並且安裝好UCenter。
如果論壇沒有安裝可以參考上篇 ---------------> 從零開始 CentOs 7 搭建論壇BBS Discuz_X3.2
據瞭解 Discuz3.x 以下的版本是不帶 UCenter 的,之前的就不去探討了,如果沒有的話另外安裝就行。這邊3.2版的論壇已經集成好了。
1、使用 admin 登陸論壇的 UCenter 控制中心,這個地方就是用 admin 登陸後進入到管理中心就可以看到菜單如下。
2、進入UCenter 後,點擊左邊菜單“應用管理”,右邊會默認出現一條信息,這是當前的論壇,UCenter 默認將論壇納入到了統一管理,這個時候就要進行我們的新應用(JAVA WEB)的添加,理論上是可集成任何項目,這也是康盛開發這個統一用戶管理中心的目的,廢話不多說下面開始配置我們的項目吧。
3、點擊當前頁面上的“添加新應用”,進行WEB項目配置如下圖。
ID:這個記住,配置WEB項目時需要。
應用類型:這個可以根據自己的項目選,如果不在裏面的選項選“其他”,這個應該對集成影響不大,猜想應該是UCenter對存在的這幾種類型的應用有更好的優化支持。
應用名稱:這個就隨意了,寫項目名稱可以,別的也行,只是爲了自己能區分。
應用的主URL:填自己的 JAVA_WEB 項目主訪問路徑,結尾帶不帶“/”貌似並不像它提示的那樣有影響。我這邊是都可以的,不過爲了避免集成過程中出現未知問題,先按這個來配,路徑結尾不帶“/”,成功後你可以測試下路徑帶“/”。
通信密鑰:這個任意字符,但一定要和JAVA_WEB裏面的配置文件一致。後面WEB配置會提到。
應用接口文件名稱:uc.php ,這個是默認的,如果改了請恢復,UCenter在與其通信時會自動轉換爲 /api/uc.php 的格式
是否開啓同步登陸:是
是否接受通知:是
這樣整個應用添加就完成了,直接提交返回到“應用管理”的主頁面看,會發現多了一條信息,這個就是你配置的應用了。
好的,相信聰明的你已經發現問題了,一個大紅X通信失敗,不用擔心,因爲我們的Web端還需要一些配置。
4、進行Java Web端的配置
a. 我們需要discuz java api的支持,裏面包含 jar 和源碼,下載地址:http://code.google.com/p/discuz-ucenter-api-for-java,當然很多朋友估計是打不開這個網站的,如果沒辦法下載,有需要可以聯繫我
b. 將下載的架包放到自己的項目中,也可以將源碼直接放到項目裏。結構如下
src/api/ucenter/Base64.java
src/api/ucenter/Client.java: 將常用的 UCenter 操作封裝成的客戶端對象,我們在項目中主要用它來與 UCenter 打交道
src/api/ucenter/PHPFunctions.java
src/api/ucenter/UC.java: 本地的 JAVA 項目用來接收 UCenter 同步命令的 Servlet接口,其訪問地址必須爲: /api/uc.php
src/api/ucenter/XMLHelper.java
src/config.properties:本地的JAVA項目與UCenter的接口配置文件( 需要根據實際環境進行配置 )
WebRoot/WEB-INF/web.xml: 主要就是將 src/api/ucenter/UC.java 定義爲 Servlet
5、進行config.properties配置
# # ================================================ # * Discuz! Ucenter API for JAVA # ================================================ # UC comunication settings # # #uc server url UC_API = http://10.10.10.14/upload/uc_server#uc ip address 可留空 UC_IP = 10.10.10.14#key UC_KEY = 123456789 #appid 這裏對應的就是你在 UCenter 新添加應用的時候ID UC_APPID = 2 #connect mode: default value is "" UC_CONNECT =
6、進行 web.xml 配置,添加下面這段。
<servlet> <servlet-name>api</servlet-name> <servlet-class>com.discuz.interfaces.bbs.api.UC</servlet-class> <load-on-startup>2</load-on-startup> </servlet> <servlet-mapping> <servlet-name>api</servlet-name> <url-pattern>/api/uc.php</url-pattern> </servlet-mapping>
7、整個配置就完成了,啓動 Web 服務器後,打開 UCenter 控制檯可以看到應用已經通訊成功了。
8、下面就是代碼整個註冊、登陸、退出了。我主要是想由 UCenter 來統一管理用戶,所以用戶標準以 UCenter 爲準,下面是我測試寫的 demo,各位僅作參考
a. 註冊
public String execute() { ActionContext ctx = ActionContext.getContext(); String tipStr =""; Client uClient = new Client(); String $returns = uClient.uc_user_register(user.getUserName(), user.getPassword(), user.getEmail()); int $uid = Integer.parseInt($returns); if ($uid <= 0) { if ($uid == -1) { tipStr = "用戶名不合法!!"; } else if ($uid == -2) { tipStr = "包含要允許註冊的詞語!!"; } else if ($uid == -3) { tipStr = "用戶名已經存在!!"; } else if ($uid == -4) { tipStr = "Email 格式有誤!!"; } else if ($uid == -5) { tipStr = "Email 不允許註冊!!"; } else if ($uid == -6) { tipStr = "該 Email 已經被註冊!!"; } else { tipStr = "未定義!!!"; } } else { System.out.println("OK:" + $returns); if(new UserDAOImpl().addUser(user)){ return SUCCESS; }else { tipStr = "平臺數據庫插入失敗!"; } } ctx.put("tip", tipStr); return ERROR; }b. 登陸
public String execute() { ActionContext ctx = ActionContext.getContext(); String tipStr = ""; if (!"".equals(user.getUserName())) { // 獲取Ucenter的登陸結果,同步其他應用的登陸狀態 Client uc = new Client(); String result = uc.uc_user_login(user.getUserName(), user.getPassword()); LinkedList<String> rs = XMLHelper.uc_unserialize(result); if (rs.size() > 0) { int $uid = Integer.parseInt(rs.get(0)); String $username = rs.get(1); String $password = rs.get(2); String $email = rs.get(3); if ($uid > 0) { System.out.println("Ucenter登陸成功: " + $username + " " + $password + " " + $email); String $ucsynlogin = uc.uc_user_synlogin($uid); System.out.println("Ucenter登陸成功: " + $ucsynlogin); // 進行自己系統的登陸權限判斷 if (user.getPassword().equals(new UserDAOImpl().checkUser(user.getUserName()))) { ctx.put("uclogin", $ucsynlogin); ctx.getSession().put("user", user); return SUCCESS; } }else if( $uid == -1) { tipStr = "用戶不存在,或者被刪除!"; }else if( $uid == -2) { tipStr = "密碼錯誤!"; }else { tipStr = "未定義!"; } ctx.put("tip", tipStr); return ERROR; } ctx.put("tip", result); } return ERROR; }上面標黃部分 $ucsynlogin ,需要把它存到session中,然後在登陸成功的主頁面上調用一下,一定要!其原理就是相當於讓瀏覽器去訪問下自己應用與另外一個應用,分別同步下雙方的cookie等操作。它的值如下:
<script type="text/javascript" src="http://192.168.15.110:8080/nocopy/api/uc.php?time=1295926163&code=c8d08KSlEZlDk4tTsjChzRYzZp2EpUierc%2FS3NLnFUviig8HvTnDNymm080JxI8Byl%2F1TW%2FveKQRlR14Io9pvR9eMD1F%2FAH3l1tuzWt3Rw9MQLrK5Lz0q8eMn5%2BAae92YBwwNlWiFWHyfyh%2FzUNC%2FA3HFnEgdX%2F61IwV" reload="1"></script頁面上直接取到這個值就行了。
<!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head> <title>高大上的店</title> <link rel="stylesheet" href="./css/style.css" type="text/css"> <script src="./js/jquery.js" type="text/javascript"></script> <script src="./js/itpbase.js" type="text/javascript"></script> <script src="./js/iframe_auto_height.js" type="text/javascript"></script> <script src="./js/menuTree.js" type="text/javascript"></script> </head> ${uclogin} <body bgcolor="#EBF9FA"> <form action=""> </form> </body> </html>c、登出
同上一樣的操作,頁面上需要加載 $ucsynlogout 。
public String execute() { ActionContext ctx = ActionContext.getContext(); String tipStr = ""; // 獲取Ucenter的登陸結果,同步其他應用的登陸狀態 Client uc = new Client(); String $ucsynlogout = uc.uc_user_synlogout(); if ($ucsynlogout != null) { ctx.getSession().clear(); ctx.put("uclogout", $ucsynlogout); // System.out.println("退出成功:" + $ucsynlogout); return SUCCESS; } ctx.put("tip", $ucsynlogout); return ERROR; }