寫在前面,要想實現整個過程的成功執行請先準備以下文件:
1. 登陸Openfire服務端以及Spark客戶端相關程序(openfire_4_0_1.exe、spark_2_7_6.exe)
2. 連接Openfire和Oracle相關的jar包(presence.jar、smack.jar、smackx-debug.jar、smackx.jar、ojdbc.jar)
Step1:安裝Openfire服務端並配置數據庫連接,配置參考《Openfire服務器安裝與配置教程》
Step2:在Eclipse等IDE開發工具中編寫Java Application程序並導入smack的3個jar包
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smackx.MessageEventManager;
/**
* Openfire服務端發送消息到指定客戶端賬號
*
* @author xiaolj
* @date 2016-01-05
*/
public class SendMsgFunc {
public static void main(String args[]) {
//參數1:openfire服務端創建的賬號(發送消息前請先用Spark客戶端登錄10000賬號)
//參數2:需要發送的消息內容
int status = sendImMessage("10000", "主減裝配一線設備異常,請及時處理!【反饋人:張三;聯繫電話:13883638681】");
System.err.println(status);
}
/**
* 根據返回狀態確認是否發送成功
*/
public static int sendImMessage(String userid, String content) {
System.out.println("開始執行消息推送");
String ip = "127.0.0.1";//服務裏IP或服務器對應主機名
String port = "5222";// 客戶端PID默認都是5222
String domain = "server-pc";//服務器主機名或IP地址
String adminid = "admin";//固定不變發起人(openfire服務器默認最高級權限賬戶)
String pwd = "admin";//固定不變(openfire服務器默認最高級權限賬戶密碼)
int on_line = 0;// 是否在線
try {
// 判斷用戶是否在線:--若出現error設置插件在線狀態任何權限訪問
String url = "http://127.0.0.1:9090/plugins/presence/status?jid="+ userid + "@server-pc&type=xml";
on_line = judgUserOnline(url);
// 建立連接發送客戶端消息
XMPPConnection con = new XMPPConnection(ip, Integer.parseInt(port));
con.login(adminid, pwd);
Chat chat = con.createChat(userid + "@" + domain);
Message msg = chat.createMessage();
msg.setSubject("系統通知消息");
msg.setBody(content);
MessageEventManager.addNotificationsRequests(msg, true, true, true, true);
chat.sendMessage(msg);
System.err.println("執行消息推送結束");
// 關閉連接
con.close();
} catch (Exception e) {
System.err.println("執行消息推送錯誤");
System.out.println("〖integration〗發送消息到OpenFire錯誤。");
e.printStackTrace();
return 3;
}
return on_line;
}
/********** 【判斷當前用戶是否在線】 ***********/
public static int judgUserOnline(String url) {
// 默認不在線
int onLineState = 0;
try {
URL oUrl = new URL(url);
URLConnection oConn = oUrl.openConnection();
InputStream inputStream = oConn.getInputStream();
if (oConn != null) {
// 讀取返回值:openfire服務器需先安裝插件並指定任意權限,重啓服務器
BufferedReader oIn = new BufferedReader(new InputStreamReader(inputStream));
if (null != oIn) {
String strFlag = oIn.readLine();
oIn.close();
if (strFlag.indexOf("type=\"error\"") >= 0) {// 訪問權限不足:openfire用戶不存在
onLineState = -1;
} else if (strFlag.indexOf("type=\"unavailable\"") >= 0) {// 用戶不在線
onLineState = 0;
} else if (strFlag.indexOf("priority") >= 0 || strFlag.indexOf("id=\"") >= 0) {// 表示用戶在線
onLineState = 1;
} else {
onLineState = 2; // 服務器發生異常
}
}
}
} catch (Exception e) {
System.err.println("執行消息推送驗證錯誤");
e.printStackTrace();
return 4;
}
System.err.println("執行消息推送驗證結束");
return onLineState;
}
}
Step3:將Java程序以及運行過程中的jar包load到Oracle數據庫
3.1) 將調用openfire相關jar包導入Oracle數據庫:
loadjava -r -f -o -user 用戶/密碼@IP:端口/實例名 D:\smack.jar
loadjava -r -f -o -user 用戶/密碼@IP:端口/實例名 D:\smackx.jar
loadjava -r -f -o -user 用戶/密碼@IP:端口/實例名 D:\smackx-debug.jar
3.2) 在Oracle中新建一個SQL窗口創建Java source程序然後將以上Java代碼拷貝其中並編譯(源文件名自定義)
create or replace and compile java source named "OpenfireClient_Func" as
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.net.URL;
import java.net.URLConnection;
import org.jivesoftware.smack.Chat;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smack.packet.Message;
import org.jivesoftware.smackx.MessageEventManager;
/**
* Openfire服務端發送消息到指定客戶端賬號
*
* @author xiaolj
* @date 2016-01-05
*/
public class SendMsgFunc {
public static void main(String args[]) {
//參數1:openfire服務端創建的賬號(發送消息前請先用Spark客戶端登錄10000賬號)
//參數2:需要發送的消息內容
int status = sendImMessage("10000", "主減裝配一線設備異常,請及時處理!【反饋人:張三;聯繫電話:13883638681】");
System.err.println(status);
}
/**
* 根據返回狀態確認是否發送成功
*/
public static int sendImMessage(String userid, String content) {
System.out.println("開始執行消息推送");
String ip = "127.0.0.1";//服務裏IP或服務器對應主機名
String port = "5222";// 客戶端PID默認都是5222
String domain = "server-pc";//服務器主機名或IP地址
String adminid = "admin";//固定不變發起人(openfire服務器默認最高級權限賬戶)
String pwd = "admin";//固定不變(openfire服務器默認最高級權限賬戶密碼)
int on_line = 0;// 是否在線
try {
// 判斷用戶是否在線:--若出現error設置插件在線狀態任何權限訪問
String url = "http://127.0.0.1:9090/plugins/presence/status?jid="+ userid + "@server-pc&type=xml";
on_line = judgUserOnline(url);
// 建立連接發送客戶端消息
XMPPConnection con = new XMPPConnection(ip, Integer.parseInt(port));
con.login(adminid, pwd);
Chat chat = con.createChat(userid + "@" + domain);
Message msg = chat.createMessage();
msg.setSubject("系統通知消息");
msg.setBody(content);
MessageEventManager.addNotificationsRequests(msg, true, true, true, true);
chat.sendMessage(msg);
System.err.println("執行消息推送結束");
// 關閉連接
con.close();
} catch (Exception e) {
System.err.println("執行消息推送錯誤");
System.out.println("〖integration〗發送消息到OpenFire錯誤。");
e.printStackTrace();
return 3;
}
return on_line;
}
/********** 【判斷當前用戶是否在線】 ***********/
public static int judgUserOnline(String url) {
// 默認不在線
int onLineState = 0;
try {
URL oUrl = new URL(url);
URLConnection oConn = oUrl.openConnection();
InputStream inputStream = oConn.getInputStream();
if (oConn != null) {
// 讀取返回值:openfire服務器需先安裝插件並指定任意權限,重啓服務器
BufferedReader oIn = new BufferedReader(new InputStreamReader(inputStream));
if (null != oIn) {
String strFlag = oIn.readLine();
oIn.close();
if (strFlag.indexOf("type=\"error\"") >= 0) {// 訪問權限不足:openfire用戶不存在
onLineState = -1;
} else if (strFlag.indexOf("type=\"unavailable\"") >= 0) {// 用戶不在線
onLineState = 0;
} else if (strFlag.indexOf("priority") >= 0 || strFlag.indexOf("id=\"") >= 0) {// 表示用戶在線
onLineState = 1;
} else {
onLineState = 2; // 服務器發生異常
}
}
}
} catch (Exception e) {
System.err.println("執行消息推送驗證錯誤");
e.printStackTrace();
return 4;
}
System.err.println("執行消息推送驗證結束");
return onLineState;
}
}
Step4:編寫Oracle函數(觸發器只需調用該函數執行Java程序,函數名自定義,java name必須是Java程序存在的類.方法(參數類型一致)
create or replace function openfire_notice_func(f_user varchar2, f_msg varchar2) return number
as
language java name 'SendMsgFunc.sendImMessage(java.lang.String, java.lang.String) return int';
Step5:這一步很關鍵,否則消息不能發送成功(Oracle權限機制,消息發送需要Socket以及文件讀取,因此需要給Oracle用戶進行授權)
請用sys登錄數據庫爲用戶授權執行【SQL命令】:
exec sys.dbms_java.grant_permission('大寫用戶名','SYS:java.net.SocketPermission', '127.0.0.1:9090', 'connect,resolve' );
exec sys.dbms_java.grant_permission('大寫用戶名','SYS:java.net.SocketPermission', '127.0.0.1:5222', 'connect,resolve' );
exec sys.dbms_java.grant_permission('大寫用戶名','SYS:java.lang.RuntimePermission', 'getClassLoader', '' );
exec sys.dbms_java.grant_permission('大寫用戶名','SYS:java.io.FilePermission', 'D:\DBHOME_1\JAVAVM\lib\security\cacerts', 'read' );
exec sys.dbms_java.grant_permission('大寫用戶名','SYS:java.io.FilePermission','<<ALL FILE>>','read,write,execute,delete');
如果未對用戶進行授權,就會拋出如下異常:
Step6:編寫Oracle觸發器程序
-- 觸發器調用Java程序執行消息發送
create or replace trigger trigger_ofuser
after insert or update on ofuser for each row
declare
--定義變量
MESSAGE_STATUS number; -- 消息發送成功返回值狀態
MESSAGE_INFO varchar2(50); -- 待發送的消息內容
begin
dbms_output.put_line('開始執行觸發器');
--RAISE_APPLICATION_ERROR(-20000, '模擬一個錯誤代碼,程序將終止');
-- 一、插入操作,
if inserting then
--1、插入用戶記錄(略)
--insert into ofuser values(...);
--2、發送消息根據返回狀態記錄通知用戶是否接收到通知,歷史跟蹤,判斷當前用戶發送消息是否成功
MESSAGE_INFO :='測試消息發送【測試人:'||:new.username||'】';
begin
select openfire_notice_func(:new.username, MESSAGE_INFO) into MESSAGE_STATUS from dual;
if (MESSAGE_STATUS = -1) then
dbms_output.put_line('通知已成功(用戶未註冊客戶端)');
elsif (MESSAGE_STATUS = 0) then
dbms_output.put_line('通知發送成功(用戶不在線)');
elsif (MESSAGE_STATUS = 1) then
dbms_output.put_line('通知發送成功(用戶已接收通知)');
elsif (MESSAGE_STATUS = 2) then
dbms_output.put_line('通知發送失敗(服務器發生異常,請稍後重試)');
else
dbms_output.put_line('通知發送失敗(服務器發生消息異常,請聯繫系統管理員)');
end if;
end;
end if;
--二、更新操作
if updating then
update ofuser t set t.plainpassword = '123456' where t.username = :new.username;
end if;
end trigger_ofuser;
Step7:編寫測試窗口進行測試
以上Oracle如何調用Java程序執行消息發送教程,若有疑問可以聯繫博主。
聲明:以上教程爲博主原創,若需轉載請註明出處,謝謝。