本例是我工作中的一些实操例子,亦是我工作日志,记录在此,既可作为我自己的总结,也可以此分享给同行借鉴。
入参是字符串格式的xml,目的是解析xml节点值,作为数据库检索where条件,检索出数据库记录,利用四个游标返回四个数据集,然后用groovy脚本将四个游标数据集解析成json出参中对应的四个节点值。出参json有两层结构,第一层是"data": [],第二层的"checkinfo": [],"bacinfo": [],"tesinfo": []节点是在"data": []层下面。
因为我用的oracle是11g的。所以需要通过自建xml解析函数配合groovy脚本来转换成json,貌似oracle 12g后的版本才有JSON_VALUE函数处理json格式数据。但我没有研究过。
第一步,创建解析xml的函数脚本如下(因为本例调用存储过程的入参是xml格式的,所以需要借助这个函数来解析下入参,取到xml对应的节点值)
CREATE OR REPLACE FUNCTION your_function(as_xml_string in clob, as_xml_mark in varchar2)
return varchar2 Is
vs_bmark varchar2(64);
vs_emark varchar2(64);
vs_source varchar2(10240);
vs_xmlval varchar2(10240);
vi_bpos integer;
vi_epos integer;
begin
vs_bmark := '<' || lower(as_xml_mark) || '>';
vs_emark := '</' || lower(as_xml_mark) || '>';
vs_source := lower(replace(replace(as_xml_string, '<![CDATA['), ']]>'));--有些xml是来自接口入参,入参会有'<![CDATA[',']]>'等字符,所以要替换掉
vi_bpos := instr(vs_source, vs_bmark);
vi_epos := instr(vs_source, vs_emark);
if vi_bpos > 0 and vi_epos > 0 then
vi_bpos := vi_bpos + length(vs_bmark);
vs_xmlval := substr(replace(replace(as_xml_string, '<![CDATA['),
']]>'),
vi_bpos,
vi_epos - vi_bpos);
end if;
return vs_xmlval;
end;
第二步,创建oracle存储过程,放在本文附件,脚本代码略多,为了不影响篇幅,此处略
第三步,JDBC调用存储过程语句如下,Jdbc调用存储过程的语句()里IN代表入参,OUT代表出参,本例入参data是从程序前端传进来的字符串xml,参考下文xml入参示例。
Call your_procedure ({IN#VARCHAR2#data},{OUT#VARCHAR2#fbusinesstype},{OUT#VARCHAR2#fmsgid},{OUT#VARCHAR2#fcreationtime},{OUT#VARCHAR2#fcode},{OUT#VARCHAR2#fresultmessage},{OUT#CURSOR#data},{OUT#CURSOR#checkinfo},{OUT#CURSOR#bacinfo},{OUT#CURSOR#tesinfo})
第四步,创建groovy脚本如下,Groovy脚本处理游标出参,groovy出来的其实是map格式,但map转json或者map转xml有很多java的工具包可用。这里不赘述。本例用了一些金蝶云的包,公司是基于Apache Camel,再把groovy集成进去,构建消息引擎中间件。每家公司都可能不一样,这里亦不赘述。
package com.kingdeehit.cloud.integration;//金蝶云包
import com.kingdeehit.cloud.core.exception.CloudBaseException; //金蝶云包
import com.kingdeehit.cloud.integration.service.IGroovyPlugin; //金蝶云包
import org.apache.camel.Exchange;
import java.util.*;
public class Groovy extends IGroovyPlugin {
@Override
public void process(Exchange exchange) {
HashMap body = (HashMap) exchange.getIn().getBody();
//获取循环外内容
String fbusinesstype = body.get("fbusinesstype");
String fcreationtime = body.get("fcreationtime");
String fmsgid = body.get("fmsgid");
String fresultmessage = body.get("fresultmessage");
String fcode = body.get("fcode");
//获取循环内容
ArrayList DataBody = (ArrayList)body.get("data");
ArrayList CheckinfoBody = (ArrayList)body.get("checkinfo");
ArrayList BacinfoBody = (ArrayList)body.get("bacinfo");
ArrayList TesinfoBody = (ArrayList)body.get("tesinfo");
//定义新body
HashMap newbody = new HashMap();
ArrayList newDataBody = new ArrayList();
for(int i=0; i< DataBody.size(); i++)//第一层"data": []节点循环取值
{
HashMap tempDataMap = (HashMap) DataBody.get(i);
String tempDataId = tempDataMap.get("freportno").toString();
ArrayList CheckDone = new ArrayList();
ArrayList BacDone = new ArrayList();
ArrayList TesDone = new ArrayList();
for(int j = 0; j< CheckinfoBody.size();j++)//第二层"checkinfo": []节点循环取值
{
HashMap tempCheckMap = (HashMap) CheckinfoBody.get(j);
String tempCheckId = tempCheckMap.get("freportno").toString();
if(tempDataId == tempCheckId)
{
CheckDone.add(tempCheckMap);
}
};
for(int k = 0; k< BacinfoBody.size();k++)//第二层"bacinfo": []节点循环取值
{
HashMap tempBacMap = (HashMap) CheckinfoBody.get(k);
String tempBacId = tempBacMap.get("freportno").toString();
if(tempDataId == tempBacId)
{
BacDone.add(tempBacMap);
}
};
for(int l = 0; l< TesinfoBody.size();l++)//第二层"tesinfo": []节点循环取值
{
HashMap tempTesMap = (HashMap) CheckinfoBody.get(l);
String tempTesId = tempTesMap.get("freportno").toString();
if(tempDataId == tempTesId)
{
TesDone.add(tempTesMap);
}
};
tempDataMap.put("checkinfo", CheckDone);
tempDataMap.put("bacinfo", BacDone);
tempDataMap.put("tesinfo", TesDone);
newDataBody.add(tempDataMap);
};
//拼装新body
newbody.put("fbusinesstype",fbusinesstype);
newbody.put("fcreationtime",fcreationtime);
newbody.put("fmsgid",fmsgid);
newbody.put("fresultmessage",fresultmessage);
newbody.put("fcode",fcode);
newbody.put("data",newDataBody);
exchange.getIn().setBody(newbody);
}
}
xml入参示例如下:
{
"data": {
"fmsgid": "*******",
"fsource": "",
"freporton": "",
"freporttimelow": "",
"freporttimehigh": "",
"finpatientno": "",
"fvisitordno": "",
"fvisittypecode": "",
"fvisittype": "",
"fwardno": "",
"fdeptno": "",
"fpatientid": "1************0",
"fidcard": ""
}
}
json出参示例:在本文附件,此处略。