WebService开发指南
WebServiceInAurora
Web Service
Web Service是一种面向服务的架构的技术,通过标准的Web协议提供服务,目的是保证不同平台的应用服务可以互操作。在Aurora框架中可以方便的提供Web
Service服务及调用由他人发布的Web Service。
在Aurora中发布Web Service
1. 从
Aurora-framework上下载最新的aurora.jar
2. 添加web service监听器。打开
WEB-HOME\WEB-INF\aurora.feature\service-listener.config,在 <participant-list category="service"> 节点下,添加 <participant class="aurora.service.ws.SOAPServiceInterpreter"/> 子节点。
3. 取消此svc的登录校验。在系统注册svc文件时,设置不需要登录的权限。对于webservice作为一个独立部署的工程,可以取消service-procedure.config配置文件,这样所有的文件都不需要登录校验。
4. 撰写svc文件,提供给他人调用即可。
简单例子
我们提供一个svc,此svc把请求的数据插入到一个数据库表中。
1. create table account_test(ACCOUNT_ID number,ACCOUNT_OTHER_CODE varchar2(100)); 新建一个对应的结果表
2. 建立一个此表的bm:
<?xml version="1.0" encoding="UTF-8"?>
<!--
$Author: linjinxiao
$Date: 2011-11-9 上午10:42:34
$Revision: 1.0
$Purpose:
-->
<bm:model xmlns:bm="http://www.aurora-framework.org/schema/bm" alias="t1" baseTable="ACCOUNT_TEST">
<bm:fields>
<bm:field name="ACCOUNT_ID" databaseType="NUMBER" datatype="java.lang.Long"
physicalName="ACCOUNT_ID" prompt="ACOUNT_TEST.ACCOUNT_ID"/>
<bm:field name="ACCOUNT_OTHER_CODE" databaseType="VARCHAR2"
datatype="java.lang.String" physicalName="ACCOUNT_OTHER_CODE" prompt="ACOUNT_TEST.ACCOUNT_OTHER_CODE"/>
</bm:fields>
</bm:model>
3. 在modules/sys目录下新建ws_test.svc文件,并输入以下内容
<?xml version="1.0" encoding="UTF-8"?>
<a:service xmlns:a="http://www.aurora-framework.org/application">
<a:init-procedure>
<a:model-insert model="fnd.account_test"/>
</a:init-procedure>
<a:service-output output="/parameter"/>
</a:service>
以上内容就完成了服务器的编写,下面提供客户端的调用代码示例
4. 使用开源框架axis2为例
public class LowLevelClient {
public static void main(String[] args) throws AxisFault {
ServiceClient client = new ServiceClient();
Options options = new Options();
options.setTo(new EndpointReference(
"http://127.0.0.1:8080/newhec/modules/sys/ws_test.svc"));//修正为实际工程的URL
client.setOptions(options);
OMElement request = makeRequest();
OMElement response = client.sendReceive(request);
System.out.println("ok:"+response.toString());
}
private static OMElement makeRequest() {
OMFactory factory = OMAbstractFactory.getOMFactory();
OMElement request = factory.createOMElement(new QName(
"", "parameter"));
request.addAttribute("ACCOUNT_ID", "123", null);
request.addAttribute("ACCOUNT_OTHER_CODE", "test", null);
return request;
}
5. 查看插入数据库记录是否成功和控制台的结果是否正确。
复杂例子
这个例子处理有头行结构的例子。譬如,调用方发送过来的请求是如下格式
<requestHead seqNo="1"/>
<requestBody>
<records>
<record ACCOUNT_ID="22" ACCOUNT_OTHER_CODE="test"/>
<record ACCOUNT_ID="33" ACCOUNT_OTHER_CODE="test2"/>
</records>
</requestBody>
返回的结构要求是如下格式
<responseHead xmlns="http://aurora.org" seqNo="1" />
<requestBody responsedate="3008900">
<records>
<record ACCOUNT_ID="22" ACCOUNT_OTHER_CODE="test" REQUEST_RESULT="successful" />
<record ACCOUNT_ID="33" ACCOUNT_OTHER_CODE="test2" REQUEST_RESULT="successful" />
</records>
</requestBody>
1. 我们创建一个pkg:
create or replace package ACCOUNT_TEST_PKG is
procedure insert_account_test(p_account_id number,
p_account_other_code varchar2,
p_request_result out varchar2);
end ACCOUNT_TEST_PKG; create or replace package body "ACCOUNT_TEST_PKG" is
procedure insert_account_test(p_account_id number,
p_account_other_code varchar2,
p_request_result out varchar2) is
begin insert into account_test
(account_id, account_other_code)
values
(p_account_id, p_account_other_code);
p_request_result := 'successful'; end;
end ACCOUNT_TEST_PKG;
/
2. 在bm中调用此pkg:
<bm:operations>
<bm:operation name="insert">
<bm:update-sql><![CDATA[
begin
ACCOUNT_TEST_PKG.insert_account_test
(
p_account_id => ${@ACCOUNT_ID},
p_account_other_code => ${@ACCOUNT_OTHER_CODE},
p_request_result => ${@REQUEST_RESULT}
);
end;
</bm:update-sql>
<bm:parameters>
<bm:parameter name="ACCOUNT_ID"/>
<bm:parameter name="ACCOUNT_OTHER_CODE"/>
<bm:parameter name="REQUEST_RESULT" output="true" outputPath="@REQUEST_RESULT"/>
</bm:parameters>
</bm:operation>
</bm:operations>
3. 撰写svc如下:
<?xml version="1.0" encoding="UTF-8"?>
<a:service xmlns:a="http://www.aurora-framework.org/application"
xmlns:p="uncertain.proc">
<a:init-procedure>
<p:echo/>
<!-- 对数据进行循环操作-->
<batch-apply sourcepath="/parameter/requestBody/records">
<a:model-insert model="fnd.account_test"/>
</batch-apply>
<!--更改节点的名称和namespace-->
<p:set-element target="/parameter/requestHead" name="responseHead" namespace="http://aurora.org" />
<!-- 获得当前的时间-->
<a:model-query fetchAll="true" fethOneRecord="true" model="ccic.systest"
rootPath="/parameter/requestBody"/>
</a:init-procedure>
<a:service-output output="/parameter/"/>
</a:service>
4. 撰写客户端调用代码,同样是利用开源框架axis2:
private static OMElement makeRequest2() {
OMFactory factory = OMAbstractFactory.getOMFactory();
OMElement request = factory.createOMElement(new QName("soap:Body"));
OMElement requestHead = factory.createOMElement(new QName("requestHead"));
requestHead.addAttribute("seqNo", "1", null);
OMElement requestBody = factory.createOMElement(new QName("requestBody "));
OMElement records = factory.createOMElement(new QName("records "));
OMElement record = factory.createOMElement(new QName("record "));
record.addAttribute("ACCOUNT_ID", "11", null);
record.addAttribute("ACCOUNT_OTHER_CODE", "test", null);
records.addChild(record);
requestBody.addChild(records);
request.addChild(requestHead);
request.addChild(requestBody);
return request;
}
5. 执行此客户端,并查询数据库记录和返回结果是否正确。
调用WebService
假设服务端要求提交的格式如下:
<axis2ns1:cancat xmlns:axis2ns1="http://www.aurora.org/simple/">
<s1>abc</s1>
<s2>def</s2>
</axis2ns1:cancat>
返回的格式如下:
<ns1:syncAccResponse xmlns:ns1=\http://service.test.com\>
<ns1:out>
<ns2:Account xmlns:ns2=\http://dto.test.com\>
<ACCOUNT_ID xmlns=\http://dto.test.com\>1681</ACCOUNT_ID>
<ACCOUNT_OTHER_CODE xmlns=\http://dto.test.com\></ACCOUNT_OTHER_CODE>
</ns2:Account>
<ns2:Account xmlns:ns2=\http://dto.test.com\>
<ACCOUNT_ID xmlns=\http://dto.test.com\>1682</ACCOUNT_ID>
<ACCOUNT_OTHER_CODE xmlns=\http://dto.test.com\></ACCOUNT_OTHER_CODE>
</ns2:Account>
</ns1:out>
</ns1:syncAccResponse>
1. 模拟第三方发布服务,以axis2为例
1. 下载
axis2
2. 把
simpleWebService部署到
AXIS2_HOME/repository/services下,然后启动服务
2. 编写客户端代码
1. 编写systest.bm文件
<?xml version="1.0" encoding="UTF-8"?>
<bm:model xmlns:bm="http://www.aurora-framework.org/schema/bm">
<bm:operations>
<bm:operation name="query">
<bm:query-sql><![CDATA[select '3008900' exp_report_number,
'222222222' employee_code,
'测试' name,
'MAS' unit_code,
'test@hand-china.com' email,
'0' type
from dual
</bm:query-sql>
</bm:operation>
</bm:operations>
</bm:model>
2. 编写svc文件
<?xml version="1.0" encoding="UTF-8"?>
<a:service xmlns:a="http://www.aurora-framework.org/application"
xmlns:p="uncertain.proc" xmlns:rs="aurora.database.rsconsumer" >
<a:init-procedure>
<!-- 构建符合的请求的格式-->
<a:model-query fetchAll="true" prefix="ns1"
nameSpace="http://www.aurora.org/simple" localName="cancat" model="sys.systest" rootPath="/model/result1"/>
<a:model-query fetchAll="true" model="sys.systest" localName="s1"
attribAsCdata="true" attribAsCdataList="unit_code"rootPath="/model/result1/cancat"/>
<a:model-query fetchAll="true" model="sys.systest" localName="s2"
attribAsCdata="true" attribAsCdataList="employee_code" rootPath="/model/result1/cancat"/>
<!-- 请求WebService-->
<a:ws-invoker raiseExceptionOnError="false" url="http://localhost:8080/axis2/services/simple"
inputPath="/model/result1/cancat" returnPath="/model/syncAccResponse"/>
<!--把子节点中cdata的内容整合成父节点中的一个属性 -->
<p:method-invoke className="uncertain.composite.CompositeUtil" methodName="collapse">
<p:arguments>
<p:argument path="/model/syncAccResponse/out" type="uncertain.composite.CompositeMap"/>
</p:arguments>
</p:method-invoke>
<as:SetParameterParsed />
<!--循环处理子节点 -->
<batch-apply sourcepath="/model/syncAccResponse/out">
<a:model-insert model="fnd.account_test"/>
</batch-apply>
</a:init-procedure>
<a:service-output output="/parameter/"/>
3. 调用此svc,并查看日志和数据库记录是否正确。
svc常用功能简介
最基本的四个功能:model-query,model-insert,model-update,model-delete
把单条记录查询结果返回的属性直接更新到指定的节点上: fetchOneRecord="true" 。例子:
<a:model-query fetchAll="true" fetchOneRecord="true" model="sys.systest" rootPath="/model/result1/cancat"/>
如果不加此属性,返回的结果是
<model>
<result1>
<concat>
<record employee_cod="test"/>
</concat>
</result1>
</model>
加了此属性后,返回结果就是:
<model>
<result1>
<concat employee_cod="test"/>
</result1>
</model>
注意:此属性仅对返回单条记录有效。
批量循环处理:batch-apply 。例子:
<batch-apply sourcepath="/model/syncAccResponse/out">
<a:model-insert model="fnd.account_test"/>
</batch-apply>
表示对/model/syncAccResponse/out下面的所有子节点执行model-insert操作。
更改查询返回的数据格式。例子:
<a:model-query fetchAll="true" model="sys.systest" localName="s2" attribAsCdata="true"
attribAsCdataList="employee_code" prefix="ns1"
nameSpace="http://www.aurora.org/simple" rootPath="/model/result1/cancat"/>
</a:model-query>
如果不加localName="s2"...nameSpace="http://www.aurora.org/simple" 那段,那么原本的返回结果可能是
<model>
<result1>
<concat>
<record employee_cod="test"/>
</concat>
</result1>
</model>
经过处理后,就变成
<model>
<result1>
<concat>
<ns1:s2 xmlns:ns1="http://www.aurora.org/simple">test</ns1:s2>
</concat>
</result1>
</model>
把cdata的内容变成父节点的一个属性,例子:
<p:method-invoke className="uncertain.composite.CompositeUtil" methodName="collapse">
<p:arguments>
<p:argument path="/model/syncAccResponse/out" type="uncertain.composite.CompositeMap"/>
</p:arguments>
</p:method-invoke>
原先的数据格式可能是这样的:
<model>
<syncAccResponse>
<out>
<s1>yes</s1>
<s2>test</s2>
</out>
</syncAccResponse1>
</model>
处理后的格式就是这样的
<model>
<syncAccResponse>
<out s1="yes" s2="test"/>
</syncAccResponse1>
</model>
复制元素属性,例子
<p:method-invoke className="uncertain.composite.CompositeUtil" methodName="copyAttributes" >
<p:arguments>
<p:argument path="/model/result4" type="java.util.Map"/>
<p:argument path="/parameter" type="java.util.Map"/>
</p:arguments>
</p:method-invoke>
原先的格式可能是这样的
<model>
<result4 s1="yes" s2="test"/>
</model>
<parameter s3="aurora" />
执行后就变成这个效果
<model>
<result4 s1="yes" s2="test"/>
</model>
<parameter s1="yes" s2="test" s3="aurora" />
更改元素名称、namespace和前缀:set-element。
例子
<p:set-element target="/model/syncAccResponse/out" name="ok" prefix="right"
namespace="http://aurora.org" childLevel="0"/>
原先的格式可能是这样的:
<model>
<syncAccResponse>
<out>
<s1>yes</s1>
<s2>test</s2>
</out>
</syncAccResponse1>
</model>
执行后变成:
<model>
<syncAccResponse>
<right:ok xmlns:right="http://aurora.org">
<s1>yes</s1>
<s2>test</s2>
</right:ok>
</syncAccResponse1>
</model>
其中childLevel表示子节点的层次,如果是0,代表本节点,如果是1,表示下一级子节点。假设把上面的childLevel改成1,然后结果会变成:
<model>
<syncAccResponse>
<out>
<right:ok xmlns:right="http://aurora.org" >yes</right:o>
<right:ok xmlns:right="http://aurora.org">test</right:o>
</out>
</syncAccResponse1>
</model>
WebService开发指南的更多相关文章
- axis2 webService开发指南(1)
参考文件:blog.csdn.net/IBM_hoojo http://hoojo.cnblogs.com/ 1 WebService简介 WebService让一个程序可以透明的调用互联网的程序,不 ...
- axis2 webService开发指南(3)
复杂对象类型的WebService 这次我们编写复杂点的WebService方法,返回的数据是我们定义属性带getter.setter方法JavaBean,一维数组.二维数组等 1.服务源代码 新建一 ...
- axis2 webService开发指南(2)
1 Axis2的简单WebService示例 1.1 新建一个web工程,创建一个类Greeting,用于当作webservice服务 代码如下: package amyservices; impo ...
- axis1,xfire,jUnit 测试案列+开Web Service开发指南+axis1.jar下载 代码
axis1,xfire,jUnit 测试案列+Web Service开发指南(中).pdf+axis1.jar下载 代码 项目和资源文档+jar 下载:http://download.csdn. ...
- ASP.NET Aries 开源开发框架:开发指南(一)
前言: 上周开源了Aries开发框架后,好多朋友都Download了源码,在运行过程里,有一些共性的问题会问到. 所以本篇打算写一下简单的开发指南,照顾一下不是太看的懂源码的同学,同时也会讲解一下框架 ...
- FreeMarker模板开发指南知识点梳理
freemarker是什么? 有什么用? 怎么用? (问得好,这些都是我想知道的问题) freemarker是什么? FreeMarker 是一款 模板引擎: 即一种基于模板和要改变的数据, 并用来生 ...
- Jetty使用教程(四:21-22)—Jetty开发指南
二十一.嵌入式开发 21.1 Jetty嵌入式开发HelloWorld 本章节将提供一些教程,通过Jetty API快速开发嵌入式代码 21.1.1 下载Jetty的jar包 Jetty目前已经把所有 ...
- JVM 平台上的各种语言的开发指南
JVM 平台上的各种语言的开发指南 为什么我们需要如此多的JVM语言? 在2013年你可以有50中JVM语言的选择来用于你的下一个项目.尽管你可以说出一大打的名字,你会准备为你的下一个项目选择一种新的 ...
- eclipse下的webservice开发
关于eclipse下的webservice开发,有非常多的教程,这里只记下学习过程中的弯路: 1.无论是CXF模式还是AXIS模式,在出现start server之后,点击next报错:"s ...
随机推荐
- Dynamics CRM2013 导入解决方案(快速视图窗体)SystemForm With Id Does Not Exist的解决方法
在CRM2013的环境下导入解决方案报错,具体报错截图如下 根据id去数据库中查找这个id的systemform,确认是存在的,而且通过第二条记录我们也可以看到这个systemform属于哪个实体,我 ...
- Dynamics CRM2016 Web Api之根据时间查询数据
我的博文里已经有多次提到CRM中的时间处理问题了,本篇继续探讨在web api的场景下时间字段如何处理,本篇只涉及查询,针对2016中新增的时间行为"用户当地时间"和"无 ...
- The Zen Programmer
专注 何为专注 关于 休息 怎么睡觉 心无杂念 我的体会 自我分析 初学者心态 无我 不要设置职业目标 敏事慎言 正念 做自己的老板 玩物养志 结语 最近在研读Christian Grobmeier ...
- ROS机器人程序设计(原书第2版)补充资料 (壹) 第一章 ROS系统入门
ROS机器人程序设计(原书第2版)补充资料 (壹) 第一章 ROS系统入门 书中,大部分出现hydro的地方,直接替换为indigo或jade或kinetic,即可在对应版本中使用. 第一章主要包括R ...
- 如果用一个循环数组q[0..m-1]表示队列时,该队列只有一个队列头指针front,不设队列尾指针rear,求这个队列中从队列投到队列尾的元素个数(包含队列头、队列尾)。
#include <iostream> using namespace std; //循环队列(少用一个空间)长度 #define M (8+1) typedef struct node ...
- Linux 高性能服务器编程——IP协议详解
1 IP服务特点 IP协议是TCP/IP协议族的动力,它为上层协议提供无状态.无连接.不可靠的服务. 无状态:IP通信双方不同步传输数据的状态信息,因此IP数据包的发送.传输和接收都是无序的. ...
- Dynamics CRM FORM脚本库加载本地脚本
用传统的开发方式,js脚本都是保存在数据库中的,这样也方便迁移,但如果不想存数据库而是存在物理磁盘上,则可通过下述代码,将脚本存放在CRMWEB文件夹的某个路径下,每次都动态引用本地JS. funct ...
- Android4.3 屏蔽HOME按键返回桌面详解(源码环境下)
点击打开链接 首先声明我是做系统开发的(高通平台),所以下面介绍的方法并不适合应用开发者. 最经有个需求要屏蔽HOME按键返回桌面并且实现自己的功能,发现以前的方式报错用不了,上网搜索了一下,发现都是 ...
- Retrofit 2.0 超能实践(三),轻松实现文件/多图片上传/Json字符串
文:http://blog.csdn.net/sk719887916/article/details/51755427 Tamic 简书&csdn同步 通过前两篇姿势的入门 Retrofit ...
- FFmpeg的H.264解码器源代码简单分析:解析器(Parser)部分
===================================================== H.264源代码分析文章列表: [编码 - x264] x264源代码简单分析:概述 x26 ...