Oracle資料庫觸發器如何呼叫Java程式實現Openfire訊息推送
阿新 • • 發佈:2019-01-29
寫在前面,要想實現整個過程的成功執行請先準備以下檔案:
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程式執行訊息傳送教程,若有疑問可以聯絡博主。
宣告:以上教程為博主原創,若需轉載請註明出處,謝謝。