这节课我们一起学习利用Mirth Connect的HTTP Listener源通道与JavaScript Writer目的通道搭建自定义Restful风格webapi服务。

1.新建名为‘Custom  Restful api’的信道,指定源通道与目的通道的输入输出消息格式

2.设置HTTP Listener类型源通道参数

  1. 把 "Response" 响应指定为 destination 1
  2. 输入‘Base  context path’ 为 /myrestservice
  3. 设置 "Message Content" 为 XML Body
  4. 设置默认"Response Content Type" 为text/plain; charset=UTF-8我们将在目的通道中通过channel map重写它的值为application/xml或application/json
  5. 设置 "Response Status Code" 响应码为 ${responseStatusCode}我们将在目的通道中通过channel map重写它的值为200(成功)或500(失败)
  6. 在 "Response Header" 中添加一个变量 "Content-Type" ,指定其值为 ${responseContentType}我们将在目的通道中通过channel map重写它的值为application/xml或application/json

3.设置JavaScript Writer目的通道参数并编写JS实现脚本

// Mirth strings don't support startsWith() in Mirth 3
// If necessary, add a method to the String prototype.
if (!String.prototype.startsWith) {
String.prototype.startsWith = function(searchString, position){
position = position || 0;
return this.substr(position, searchString.length) === searchString;
};
} /*
Incoming message looks like this: <HttpRequest>
<RemoteAddress>71.127.40.115</RemoteAddress>
<RequestUrl>http://www.example.com:8080/myrestservice</RequestUrl>
<Method>GET</Method>
<RequestPath>foo=bar</RequestPath>
<RequestContextPath>/myrestservice/param1/param2</RequestContextPath>
<Parameters>
<foo>bar</foo>
</Parameters>
<Header>
<Host>www.example.com:8080</Host>
<Accept-Encoding>identity</Accept-Encoding>
<User-Agent>Wget/1.18 (darwin15.5.0)</User-Agent>
<Connection>keep-alive</Connection>
<Accept>application/xml</Accept>
</Header>
<Content/>
</HttpRequest> <HttpRequest>
<RemoteAddress>71.127.40.115</RemoteAddress>
<RequestUrl>http://www.example.com:8080/myrestservice</RequestUrl>
<Method>GET</Method>
<RequestPath>foo=bar</RequestPath>
<RequestContextPath>/myrestservice/param1/param2</RequestContextPath>
<Parameters>
<foo>bar</foo>
</Parameters>
<Header>
<Host>www.example.com:8080</Host>
<Accept-Encoding>identity</Accept-Encoding>
<User-Agent>Wget/1.18 (darwin15.5.0)</User-Agent>
<Connection>keep-alive</Connection>
<Accept>application/json</Accept>
</Header>
<Content/>
</HttpRequest>
*/ // Just in case we fail, set a sane responseContentType
channelMap.put('responseContentType', 'text/plain'); var msg = XML(connectorMessage.getRawData());
logger.info(msg);
// Get the REST data from the "context path" which is actually
// the "path info" of the request, so it will start with '/myrestservice'.
var rest = msg['RequestContextPath'];
logger.info(rest);
var myServicePrefix = '/myrestservice';
var minimumURLParameterCount = 4; // This is the minimum you require to do your work
var maximumExpectedURLParameterCount = 5; // however many you expect to get
var params = rest.substring(myServicePrefix).split('/', maximumExpectedURLParameterCount);
if(params.length < minimumURLParameterCount)
return Packages.com.mirth.connect.server.userutil.ResponseFactory.getErrorResponse('Too few parameters in request');
var mrn = params[1]; // params[0] will be an empty string
logger.info(mrn);
// Now, determine the client's preference for what data type to return (XML vs. JSON).
// We will default to XML.
var clientWantsJSON = false;
var responseContentType = 'text/xml'; // If we see any kind of JSON before any kind of XML, we'll use
// JSON. Otherwise, we'll use XML.
//
// Technically, this is incorrect resolution of the "Accept" header,
// but it's good enough for an example.
var mimeTypes = msg['Header']['Accept'].split(/\s*,\s*/);
for(var i=0; i<mimeTypes.length; ++i) {
var mimeType = mimeTypes[i].toString();
if(mimeType.startsWith('application/json')) {
clientWantsJSON = true;
responseContentType = 'application/json';
break;
} else if(mimeType.startsWith('application/xml')) {
clientWantsJSON = false;
responseContentType = 'application/xml';
break;
} else if(mimeType.startsWith('text/xml')) {
clientWantsJSON = false;
responseContentType = 'text/xml';
break;
}
} var xml;
var json; if(clientWantsJSON)
json = { status : '' };
else
xml = new XML('<response></response>'); try {
/*
Here is where you do whatever your service needs to actually do.
*/ if(clientWantsJSON) {
json.data = { foo: 1,
bar: 'a string',
baz: [ 'list', 'of', 'strings']
};
} else {
xml['@foo'] = 1;
xml['bar'] = 'a string';
xml['baz'][0] = 'list';
xml['baz'][1] = 'of';
xml['baz'][3] = 'strings';
} // Set the response code and content-type appropriately.
// http://www.mirthproject.org/community/forums/showthread.php?t=12678 channelMap.put('responseStatusCode', 200); if(clientWantsJSON) {
json.status = 'success';
var content = JSON.stringify(json);
channelMap.put('responseContent', content);
channelMap.put('responseContentType', responseContentType);
return content;
} else {
channelMap.put('responseContentType', responseContentType);
var content = xml.toString();
channelMap.put('responseContent', content);
return content;
}
}
catch (err)
{
channelMap.put('responseStatusCode', '500');
if(clientWantsJSON) {
json.status = 'error';
if(err.javaException) {
// If you want to unpack a Java exception, this is how you do it:
json.errorType = String(err.javaException.getClass().getName());
json.errorMessage = String(err.javaException.getMessage());
} channelMap.put('responseContentType', responseContentType); // Return an error with our "error" JSON
return Packages.com.mirth.connect.server.userutil.ResponseFactory.getErrorResponse(JSON.stringify(json));
} else {
if(err.javaException) {
xml['response']['error']['@type'] = String(err.javaException.getClass().getName());
xml['response']['error']['@message'] = String(err.javaException.getMessage());
} channelMap.put('responseContentType', responseContentType); // Return an error with our "error" XML
return Packages.com.mirth.connect.server.userutil.ResponseFactory.getErrorResponse(xml.toString());
}
}

我们通过目的通道以上JS脚本,学习到以下特别重要的知识:

  1. 获取输入请求的原始消息并自动格式化为XML格式: var xml = new XML(connectorMessage.getRawData())
  2. 设置响应类型,如:channelMap.put('responseContentType', 'application/json')
  3. 设置响应码,如:channelMap.put('responseStatusCode', '200')
  4. 设置响应内容并通过JS脚本返回XML实体或者Json实体的字符串格式值
  5. 异常处理通过JS脚本调用Mirth的API函数Packages.com.mirth.connect.server.userutil.ResponseFactory.getErrorResponse(string)返回字符串格式错误消息

4.部署信道并测试 

发送消息要区分application/json和application/xml,可以看到响应值格式会相应变化

<HttpRequest>
<RemoteAddress>71.127.40.115</RemoteAddress>
<RequestUrl>http://www.example.com:8080/myrestservice</RequestUrl>
<Method>GET</Method>
<RequestPath>foo=bar</RequestPath>
<RequestContextPath>/myrestservice/param1/param2</RequestContextPath>
<Parameters>
<foo>bar</foo>
</Parameters>
<Header>
<Host>www.example.com:8080</Host>
<Accept-Encoding>identity</Accept-Encoding>
<User-Agent>Wget/1.18 (darwin15.5.0)</User-Agent>
<Connection>keep-alive</Connection>
<Accept>application/json</Accept>
</Header>
<Content/>
</HttpRequest>

  

<HttpRequest>
<RemoteAddress>71.127.40.115</RemoteAddress>
<RequestUrl>http://www.example.com:8080/myrestservice</RequestUrl>
<Method>GET</Method>
<RequestPath>foo=bar</RequestPath>
<RequestContextPath>/myrestservice/param1/param2</RequestContextPath>
<Parameters>
<foo>bar</foo>
</Parameters>
<Header>
<Host>www.example.com:8080</Host>
<Accept-Encoding>identity</Accept-Encoding>
<User-Agent>Wget/1.18 (darwin15.5.0)</User-Agent>
<Connection>keep-alive</Connection>
<Accept>application/xml</Accept>
</Header>
<Content/>
</HttpRequest>
 

大功告成!!!

本课程总结:

通过JS脚本编程,自定义实现Restful风格webapi.

欢迎大家持续关注潤沁網路大學本系列Mirth Connect课程的教学

第11課-Channel Study For Create Custom Restful Service的更多相关文章

  1. How to Create Custom Filters in AngularJs

    http://www.codeproject.com/Tips/829025/How-to-Create-Custom-Filters-in-AngularJs Introduction Filter ...

  2. create custom launcher icon 细节介绍

    create custom launcher icon 是创建你的Android app的图标 点击下一步的时候,出现的界面就是创建你的Android的图标 Foreground: ” Foregro ...

  3. [转]How to Create Custom Filters in AngularJs

    本文转自:http://www.codeproject.com/Tips/829025/How-to-Create-Custom-Filters-in-AngularJs Introduction F ...

  4. How to: Create Custom Configuration Sections Using ConfigurationSection

    https://msdn.microsoft.com/en-us/library/2tw134k3.aspx You can extend ASP.NET configuration settings ...

  5. java中如何创建自定义异常Create Custom Exception

    9.创建自定义异常 Create Custom Exception 马克-to-win:我们可以创建自己的异常:checked或unchecked异常都可以, 规则如前面我们所介绍,反正如果是chec ...

  6. Custom Data Service Providers

    Custom Data Service Providers Introduction Data Services sits above a Data Service Provider, which i ...

  7. Unable to create Azure Mobile Service: Error 500

    I had to go into my existing azure sql database server and under the configuration tab select " ...

  8. Cannot create container for service peer1.org2.example.com: Conflict. 解决方案

    I have a docker-compose.yaml file defining 5 services: orderer.example.com peer0.org1.example.com pe ...

  9. docker启动报错解决及分析(Cannot create container for service *******: cannot mount volume over existing file, file exists /var/lib/docker/overlay2/)

    现象: Cannot create container for service *******: cannot mount volume over existing file, file exists ...

  10. [转]Create Custom Exception Filter in ASP.NET Core

    本文转自:http://www.binaryintellect.net/articles/5df6e275-1148-45a1-a8b3-0ba2c7c9cea1.aspx In my previou ...

随机推荐

  1. vscode复制相对路径时是反斜杠\,改为正斜杠/ [转]

    痛点:复制路径的时候斜杠不对 解决:explorer.copyRelativePathSeparator 设置 在跳出来的设置页面的搜索栏里输入explorer.copyRelativePathSep ...

  2. Rust GUI库 egui 的简单应用

    目录 简介 简单示例 创建项目 界面设计 切换主题 自定义字体 自定义图标 经典布局 定义导航变量 实现导航界面 实现导航逻辑 实现主框架布局 调试运行 参考资料 简介 egui(发音为"e ...

  3. day03-模块化编程

    模块化编程 1.基本介绍 传统的非模块化开发有如下的缺点:(1)命名冲突(2)文件依赖 JavaScript代码越来越庞大,JavaScript引入模块化编程,开发者只需要实现核心的业务逻辑,其他都可 ...

  4. 3DCAT实时云渲染赋能聚好看科技,打造3D沉浸式互动视频云平台

    随着5G.云计算.XR等技术的发展,3D沉浸式互动视频已经成为了新一代的数字媒体形式,为各行各业带来了新的创新机遇和价值.然而,要实现高效.高质.高效率的3D沉浸式互动视频生产和传播,还需要强大的技术 ...

  5. 3DCAT携手华为,打造XR虚拟仿真实训实时云渲染解决方案

    2023年5月8日-9日,以 ''因聚而生 众志有为'' 为主题的 ''华为中国合作伙伴大会2023'' 在深圳国际会展中心隆重举行.本次大会汇聚了ICT产业界的广大新老伙伴朋友,共同探讨数字化转型的 ...

  6. 为什么延迟删除可以保证MYSQL 与redis的一致性?

    看过很多保持MYSQL 与redis保持一致性的文章都提到了延迟删除,其实脱离任何业务场景的设计都是不切实际的,所以我会本着一个通用的读写场景去分析为什么延迟删除大概率可以保证MYSQL与redis的 ...

  7. JavaScript知识总结 原型篇

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 1. 对原型.原型链的理解 在JavaScript中是使用构造函数来新建一个对象的,每一个构造函数的内部都有一个 prototype 属性 ...

  8. 在ubuntu安装QT

    在ubuntu安装 安装motrix motrix下载 下载对应版本的QT QT下载 授权run文件 sudo chmod +x xxx.run 运行run文件 ./ xxx.run 运行界面 安装完 ...

  9. KingbaseES V8R6 中walminer的使用

    前言 walminer工具可以帮助dba挖掘wal日志中的内容,看到某时间对应数据库中的具体操作.例如挖掘日志后可以看到数据库某时间有哪些dml语句. walminer的限制与约束 WalMiner工 ...

  10. 初学STM32 CAN通信(一)

    # 初学STM32 CAN通信(一) 1. CAN协议简介 ​ CAN是控制器局域网络(Controller Area Network)的简称, 是国际上应用最广泛的现场总线之一 ,近年来,它具有的高 ...