`

使用Sinatra创建Soap Web Service

 
阅读更多
简单对象访问协议(SOAP)是一种轻量的、简单的、基于 XML 的协议,它被设计成在 WEB 上交换结构化的和固化的信息。 SOAP 可以和现存的许多因特网协议和格式结合使用,包括超文本传输协议( HTTP),简单邮件传输协议(SMTP),多用途网际邮件扩充协议(MIME)。它还支持从消息系统到远程过程调用(RPC)等大量的应用程序。

本文中得示例是Soap与Http结合的Web service。其实现了一个简单的Echo和Reverse Echo的服务,既请求原文返回和请求倒序返回。就纯技术层面来说,本质上就是post 一个制造xml格式的请求,获得一个xml格式的response的Http Request。

首先,使用xsd明确request和response的xml结构
<?xml version="1.0" encoding="UTF-8"?>
<xs:schema targetNamespace="http://www.xianlinbox.net/echo" xmlns="http://www.xianlinbox.com/echo" xmlns:xs="http://www.w3.org/2001/XMLSchema" attributeFormDefault="qualified" elementFormDefault="qualified">
  <xs:complexType name="EchoMessageType">
    <xs:sequence>
      <xs:element name="Message" type="xs:string" minOccurs="1" />
    </xs:sequence>
  </xs:complexType>
  <xs:element name="EchoRequest" type="EchoMessageType"/>
  <xs:element name="EchoResponse" type="EchoMessageType"/>
  <xs:element name="ReverseEchoRequest" type="EchoMessageType"/>
  <xs:element name="ReverseEchoResponse" type="EchoMessageType"/>
</xs:schema>

然后,创建http服务
require 'bundler'
Bundler.setup
require 'sinatra/base'
	# XML 解析需用到nokogiri
require 'nokogiri'
require 'builder'

class EchoService < Sinatra::Base

  set :root, File.dirname(__FILE__)


  # 添加http basic authentication
  use Rack::Auth::Basic, "Restricted Area" do |username, password|
    username == 'admin' and password == 'admin'
  end

  # 创建Soap消息异常对象
  module SoapFault
    class MustUnderstandError < StandardError
      def fault_code
        "MustUnderstand"
      end
    end

    class ClientError < StandardError
      def fault_code
        "Client"
      end
    end
  end
	# SOAP要求SOAP messages使用Content-Type:text/xml,Sinatra默认的是application/xml,因此需配置。 
  configure do
     mime_type :xml, "text/xml"
  end
  
	#xsd读取request和response的schema, xslt用于从soap message中获取消息体,
  def initialize(*args)
    @xsd = Nokogiri::XML::Schema(File.read("#{File.dirname(__FILE__)}/public/echo_service.xsd"))
    @xslt = Nokogiri::XSLT(File.read("#{File.dirname(__FILE__)}/lib/soap_body.xslt"))
    super
  end

  # SOAP endpoint
  post '/echo_service' do
    begin
      soap_message = Nokogiri::XML(request.body.read)
      # 通过消息头来判断是否是当前服务可处理的消息。
      raise(SoapFault::MustUnderstandError, "SOAP Must Understand Error", "MustUnderstand") if soap_message.root.at_xpath('//soap:Header/*[@soap:mustUnderstand="1" and not(@soap:actor)]', 'soap' => 'http://schemas.xmlsoap.org/soap/envelope/')
      # 获取消息体
      soap_body = @xslt.transform(soap_message)
      # 通过schema验证request的结构是否合法。
      errors = @xsd.validate(soap_body).map { |e| e.message }.join(", ")
      # 如果request格式不正确,抛错。
      raise(SoapFault::ClientError, errors) unless errors == ""
      # 从request中获取该request请求的操作,通过动态分发的方式发送到对应的处理方法。
      self.send(soap_operation_to_method(soap_body), soap_body)
    rescue StandardError => e
      fault_code = e.respond_to?(:fault_code) ? e.fault_code : "Server"
      halt(500, builder(:fault, :locals => {:fault_string => e.message, :fault_code => fault_code}))
    end
  end

  private

  # 解析消息体获取request请求的操作。
  def soap_operation_to_method(soap_body)
    method = soap_body.root.name.sub(/Request$/, '').gsub(/([A-Z]+)([A-Z][a-z])/, '\1_\2').gsub(/([a-z\d])([A-Z])/, '\1_\2').downcase.to_sym
  end

  # Echo服务的具体处理函数
  def echo(soap_body)
    message = soap_body.root.at_xpath('//echo:Message/text()', 'echo' => 'http://www.without-brains.net/echo').to_s
    builder(:echo_response, :locals => {:message => message})
  end

  # ReverseEcho服务的具体处理函数
  def reverse_echo(soap_body)
    message = soap_body.root.at_xpath('//echo:Message/text()', 'echo' => 'http://www.without-brains.net/echo').to_s.reverse!
    builder(:reverse_echo_response, :locals => {:message => message})
  end
end


通过使用builder可以更方便的构建response的内容,
Fault Builder
xml.SOAP(:Envelope, "xmlns:SOAP" => "http://schemas.xmlsoap.org/soap/envelope/") do
  xml.SOAP :Body do
    xml.SOAP :Fault do
      xml.faultcode "SOAP:#{fault_code}"
      xml.faultstring fault_string
    end
  end
end


EchoResponse Builder
xml.SOAP(:Envelope, "xmlns:SOAP" => "http://schemas.xmlsoap.org/soap/envelope/", "xmlns:echo" => "http://www.without-brains.net/echo") do
  xml.SOAP :Body do
    xml.echo :EchoResponse do
      xml.echo(:Message, message)
    end
  end
end


ReverseEchoRespose Builder
xml.SOAP(:Envelope, "xmlns:SOAP" => "http://schemas.xmlsoap.org/soap/envelope/", "xmlns:echo" => "http://www.without-brains.net/echo") do
  xml.SOAP :Body do
    xml.echo :ReverseEchoResponse do
      xml.echo(:Message, message)
    end
  end
end


That's all!
0
0
分享到:
评论

相关推荐

    PHP版本的Sinatra极其轻量优雅的web领域专用语言框架

    【描述】提到"Sinatra的一个PHP复制:用于以最少的工作量在PHP中快速创建Web应用程序的DSL",这里的关键点是Domain-Specific Language(DSL),即领域特定语言。DSL是一种设计用来解决特定领域问题的语言,Pinatra...

    jfry,java fry是一个受sinatra启发的web库.zip

    使用Java Fry,开发者可以快速搭建轻量级Web应用,享受类似于Sinatra的开发体验,同时充分利用Java的强大特性和生态系统。如果你是Java开发者并寻求一个轻量级的Web框架,Java Fry是一个值得尝试的选择。

    jump star sinatra sinatra教程

    2010 年初,他创建了“IDidItMyWay”博客来记录自己学习 Sinatra 的过程,并在同年利用 Sinatra 构建了 Cards in the Cloud 网站。目前,Darren 在 RubySource 撰写关于 Sinatra 的教程,并居住在曼彻斯特,业余时间...

    webapp-training:使用Sinatra进行新员工培训的Web应用开发体验项目

    网络应用开发经验 我希望您将体验到超级简单的 Web 应用程序创建,这将是...使用 Sinatra(Web 框架)创建一个 Todo 应用程序,它相对轻量级,一开始没有太多额外的东西。 这只是一种体验,所以我不会详细介绍Ruby等。

    Sinatra并发性提升扩展Sinatra::Synchrony.zip

    Sinatra::Synchrony是 Sinatra的一个小扩展,它动态提升了Sinatra网络应用的并发性。由于EventMachine和EM-Synchrony的支持,当你有很多 传输和低速IO请求时(如向外部APIs发送的HTTP请求),它增加了你的应用每个...

    sinatra-pubsub, 为 Sinatra 推送&流.zip

    sinatra-pubsub, 为 Sinatra 推送&流 Sinatra::PubSubPubSub是对 Sinatra的扩展,它增加了使用HTML5服务器发送事件的基本发布/订阅流。例如客户端可以订阅以下事件:var es = new EventSource('/subscribe

    padrino-note:基于 Sinatra 的 Padrino Web 框架学习笔记

    Study notes for Padrino web framework英文名:Study notes for Padrino web framework中文名:Padrino学习笔记简介在使用Ruby语言的Web开发框架中,Rails和Sinatra是最流行的两个。由于Sinatra只提供了Web开发最...

    what-to-do-today:使用此基于Sinatra的Web应用程序,用户可以创建一个帐户并轻松管理他们每天需要完成的任务

    Sinatra是Ruby编程语言中的一个轻量级、高效的Web开发框架,它使得创建HTTP服务器和Web应用变得简单直观。这个项目的目标是提供一个用户友好的平台,让用户能够方便地创建账户,并在此账户下管理他们的待办事项。 *...

    sinatra_web_app_1

    在 "sinatra_web_app_1" 这个项目中,我们很显然正在探讨如何使用 Sinatra 构建一个基础的 web 应用。 首先,让我们深入了解一下 Sinatra 的核心概念: 1. **路由(Routes)**:Sinatra 的基础是路由系统,它允许...

    Ruby-Padrino一个构建在Sinatra上的全堆栈ruby框架

    Ruby-Padrino是一个基于Sinatra的全功能Web开发框架,它为开发者提供了更高级别的抽象和组织结构,使得创建复杂的Web应用变得更加简单高效。在Ruby社区中,Sinatra被誉为轻量级、简洁的HTTP服务器接口库,而Padrino...

    almost-sinatra, Sinatra 重构,现在只有六个行 比一双袜子更受欢迎.zip

    almost-sinatra, Sinatra 重构,现在只有六个行 比一双袜子更受欢迎 几乎 Sinatra "until programmers stop acting like obfuscation is morally hazardous,they're not artists, just kid

    sinatra-redis-docker-example:使用 Sinatra 和 Redis 的 dockerized JSON API 的超级简单示例

    这是一个使用 Sinatra 和 Redis 构建的 dockerized 示例 JSON API。 我希望有人能从中吸取教训。 这个例子真的很小,并且使用了和的 Docker 库容器。 最有趣的部分是您必须进行的更改才能在 Docker 容器之间启用...

    sinatra-template-源码.rar

    Sinatra是一个轻量级的Ruby框架,用于构建Web应用程序。它以其简洁、直观的语法著称,使得开发者能够快速地搭建RESTful Web服务。在"sinatra-template-源码.rar"这个压缩包中,我们有机会深入理解Sinatra的工作原理...

    sinatra-respond_to:用于Sinatra中内置Web服务支持的response_to样式Rails块

    在Sinatra中提供对内置Web服务支持的response_to样式Rails块 功能/问题: 根据提供的内容处理内容类型的设置 自动可以调整XMLHttpRequests返回Javascript 根据HTTP_ACCEPT标头解析识别请求。 优先级的顺序是...

    emque-web:提供Sinatra应用程序Web界面,用于监控消耗大笔费用的服务

    安装将此行添加到您的应用程序的Gemfile中: gem 'emque-web'# if you require 'sinatra' you get the DSL extended to Objectgem 'sinatra' , '~&gt; 1.3' , :require =&gt; nil 然后执行: $ bundle用法将以下内容添加到...

    playlister-sinatra-web-012918

    Sinatra播放列表目标巩固您对ActiveRecord的理解建立所有模型的基本视图创建用于编辑和创建新歌曲的表格,以返回结构良好的params哈希值概述以从简单的命令行应用程序静态网站转换为动态Web应用程序为主题,是时候...

    sinatra:穿着DSL(官方规范仓库)的经典Web开发

    Sinatra是一种用于以最少的精力在Ruby中快速创建Web应用程序: # myapp.rb require 'sinatra' get '/' do 'Hello world!' end 安装gem: gem install sinatra 并运行: ruby myapp.rb 查看位于: 重新启动...

    webservices的开发图片和文档

    - 开发Web服务,开发者可以使用各种工具和框架,如Java的JAX-WS和JAX-RS,Python的Flask或Django,Ruby的Sinatra,以及.NET Framework的WCF(Windows Communication Foundation)等。 7. **测试Web服务** - 工具...

    crm-web:使用 Sinatra 构建的小型客户关系管理 (CRM) 应用程序

    标签"HTML"指出了应用的前端部分至少使用了HTML(超文本标记语言),这是一种用于创建网页的标准标记语言,是构建Web页面的基础。 **文件列表分析:** 虽然没有提供具体的文件内容,但"crm-web-master"很可能是一...

    simple-chat-server:使用Sinatra和ActiveRecord的非常简单的聊天服务器

    【标题】"simple-chat-server:使用Sinatra和ActiveRecord的非常简单的聊天服务器"涉及的核心知识点主要集中在Ruby编程语言、Sinatra框架以及ActiveRecord ORM(对象关系映射)库上。以下是对这些关键技术的详细说明...

Global site tag (gtag.js) - Google Analytics