您的位置:首页 > 数据库 > Oracle

Oracle数据库触发器如何调用Java程序实现Openfire消息推送

2016-04-23 22:44 701 查看
写在前面,要想实现整个过程的成功执行请先准备以下文件:

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程序执行消息发送教程,若有疑问可以联系博主。

声明:以上教程为博主原创,若需转载请注明出处,谢谢。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: