Oracle实现监听表变化并利用Java调用WebService获取数据思路

前段时间接到了这样的需求。有两套网络隔绝的Oracle数据库(假设为数据库A和数据库B)(A可以连接互联网,B处于封闭局域网内不可连接互联网),两者进行数据交换是通过某设备将A的表的变化通过insert插入到B的对应表中,同样地,B在进行数据处理后要通过某设备将B的表的变化通过insert插入到A的对应表中。详细流程如下图所示。

从整个流程中我们可以找到该项目的技术要点在于Oracle调用WebService取回JSON数据并进行解析。我们很容易的想到要利用Oracle触发器+存储过程来完成这一任务。

在查阅相关资料后,我们找到了实现调用WebService的三种途径,它们分为两大思路。第一个思路是通过Oracle自身的存储过程调用,这需要引入UTL_DBWS或者UTL_HTTP进行调用。笔者曾经尝试了这两种方式,发现:这两种方式要求严格的SOAP报文格式,普适性并不够强。由于笔者所调用WebService的环境较为特殊,不能经常调用进行测试。因此,笔者抛弃了这两种普适性不强的策略。有兴趣的读者可以自行Google以上两个关键字,这里不再赘述。而第二个思路是通过Oracle调用Java程序进行WebService,因为Java环境下存在AXIS这样的第三方库,我们可以方便的获取WebService数据。这种思路的难点便变成了向Oracle中导入相关JAR包。

首先介绍一下本次项目的环境:

操作系统:RHEL 6.4 (Linux)

Oracle数据库:Oracle 11g

Oracle JVM版本:jdk_1_5_17

1. 确定Oracle JVM版本

确定Oracle JVM版本对于Java项目的编译至关重要,由于不同Oracle版本的数据库自带JVM版本不同(且比较低),因此,我们需要进行版本的确认。方法如下:

在终端依次输入以下命令:

①切换至Oracle用户

su oracle

[密码]

②初始化Oracle环境

. oraenv

[实例名]

③切换至$ORACLE_HOME目录

cd $ORALCE_HOME/jdk/bin

④调用java -version命令

./java -version

至此我们可以确定JVM的版本,然后在后续编程中需要把eclipse的编译器和Library版本全部改为刚才查到的版本,小版本号也要确保一致。(jdk需要从Oracle官网下载指定版本)

2. 编写Java程序

我们这里采用的是AXIS2方案,首先从WSDL文件生成相关的WebService类,然后新建一个Main类,声明一个main方法,在这里我只列举主要代码,如果各位读者需要进一步的帮助,请联系我的简信或者email我。

public  static void main(String arg1, String arg2){

    IDataQueryWSPortTypeProxy proxy = new IDataQueryWSPortTypeProxy();

    proxy.setEndpoint("http://XX.XX.XX.XX:XXXX/dataquery");

    JSONObject jo= new JSONObject();

    JSONArray ja = new JSONArray();

    ja.add(arg1);

    jo.put("aaaa", "123");

    jo.put("bbbb",ja);

    String senderID = "0523";

    String serviceID = "2356";

    String [] endUser = null; 

    String dataObjectCode = null;

    String [] requiredItems = {"cccc","dddd"};

    String condition = jo.toString();

    String infoCodeMode = null;

    String res = proxy.query(senderID, serviceID, endUser, dataObjectCode, condition, requiredItems, infoCodeMode, arg1, arg2);

}

注意,main函数的参数根据大家不同的需求最好更改为需要查询的条件参数,这样的函数在eclipse是无法运行的,但是在Oracle下可以运行,在大家调试Java程序时可以先使用String[] args参数进行,最后在打包生成JAR包前改为笔者这样的参数格式,方便Oracle调用。

由于笔者这里的搭建环境特殊,使用了eclipse进行Java的编写,因此笔者这里使用了Fatjar插件进行打包,可以轻松的将全部JAR引用包打在一起。打包成JAR包的过程这里不再赘述。

2. 配置Oracle用户权限

考虑到Oracle数据库安全,在对数据库B进行操作时,要独立使用一个用户进行管理。现在要求该用户权限至少等同于默认SCOTT用户权限,并且还要附加以下权限。先以sysdba身份登录sqlplus然后执行以下命令授权(用户名必须为英文大写字母)(请将SCOTT替换为你所使用的用户):

grant CREATE PUBLIC SYNONYM to SCOTT;

call dbms_java.grant_permission('SCOTT','SYS:java.lang.RuntimePermission', 'shutdownHooks', '' );

call dbms_java.grant_permission('SCOTT','SYS:java.util.logging.LoggingPermission', 'control', '' );

call dbms_java.grant_permission('SCOTT','SYS:java.util.PropertyPermission','http.proxySet','write');

call dbms_java.grant_permission('SCOTT','SYS:java.util.PropertyPermission','http.proxyHost', 'write');

call dbms_java.grant_permission('SCOTT','SYS:java.util.PropertyPermission','http.proxyPort', 'write');

call dbms_java.grant_permission('SCOTT','SYS:java.lang.RuntimePermission','getClassLoader','');

call dbms_java.grant_permission('SCOTT','SYS:java.net.SocketPermission','*','connect,resolve');

call dbms_java.grant_permission('SCOTT','SYS:java.util.PropertyPermission','*','read,write');

call dbms_java.grant_permission('SCOTT','SYS:java.lang.RuntimePermission','setFactory','');

call dbms_java.grant_permission('SCOTT','SYS:java.lang.RuntimePermission', 'accessClassInPackage.sun.util.calendar','');

请确认以上语句全部执行成功后在进行后续操作。

3. 导入编译好的JAR包

在准备好Oracle环境后,用SSH将打包好的JAR包导入到$ORACLE_HOME/sqlj/lib下,在终端执行以下命令完成导包工作:

①切换至lib目录下

cd $ORACLE_HOME/sqlj/lib

②执行导包命令(假设JAR文件名为rpcinvoke.jar,用户名密码分别为SCOTT/tiger)

loadjava -u SCOTT/tiger -r -v -f -s -grant public -genmissing rpcinvoke.jar >& loadjava.txt

请耐心等待导包结束,在本文末尾我会提供我调用WebService时引用的全部第三方JAR包,各位读者可以参考使用。导包完成后的日志文件将存储在该目录下的loadjava.txt中,请查看并确定除了oracle jdbc以外其他包导入成功未报异常,这说明WebService的JAVA程序将可以成功运行。

4. 编写存储过程

(1)编译JAVA SOURCE

在PL/SQL或者sqlplus以SCOTT(你所使用的用户)身份登录,执行下面的语句:

create or replace and compile java source named InvokeIDRPC as package wms;

import com.edward.wsdldemo.Main;

public class InvokeIDRPC{

public static void invokeIDRPC(String arg1, String arg2)

{

Main.main(arg1,arg2);

}

}

注意其中的Main.main()方法,代表你所使用的类名.main方法,并且确认你需要传入的参数(这里是arg1和arg2),执行此语句可以将JAVA SOURCE编译到Oracle中。

(2)编写存储过程

create or replace procedure InvokeIDRPC_P( arg1 in VARCHAR2,arg2 in VARCHAR2) as language java name 'wms.InvokeIDRPC.invokeIDRPC(java.lang.String,java.lang.String)';

这里要注意指定参数在存储过程的类型以及在JAVA程序中的类型,对应我的字符串格式就是VARCHAR2和java.lang.String类型。同时也要注意wms指明了刚才java source的package,InvokeIDRPC指明了JAVA SOURCE类的名称,而invokeIDRPC指明了JAVA SOURCE类中方法的名称。

(3)编写触发器

create or replace trigger InvokeIDRPC_T

before insert

on request_data

for each row

begin

InvokeIDRPC_P(:new.arg1,:new.arg2);

end;

这个触发器指明了在request_data表插入数据后取得arg1和arg2字段的值并传入刚才编写好的存储过程中执行。

5. 总结

以上是Oracle实现监听表变化并利用Java调用WebService获取数据的完整思路,笔者经过了实际项目测试,爬了好多坑,如果各位读者遇到其他问题可以随时简信,文章相关文件如下:

百度云:链接: https://pan.baidu.com/s/1c2m0zgk 密码: zec4

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 159,569评论 4 363
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,499评论 1 294
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,271评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,087评论 0 209
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,474评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,670评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,911评论 2 313
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,636评论 0 202
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,397评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,607评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,093评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,418评论 2 254
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,074评论 3 237
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,092评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,865评论 0 196
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,726评论 2 276
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,627评论 2 270

推荐阅读更多精彩内容