Code Monkey home page Code Monkey logo

jruby-cxf's Introduction

JRuby CXF Gem Version

JRuby CXF is a JRuby gem that wraps the Apache CXF framework to provide a friendlier API for publishing SOAP Web Services.

Requirements

JRuby CXF was tested with JRuby 1.7.4 and Apache CXF 2.7.6.

Getting started

  1. From your console install the gem: jruby -S gem install jruby-cxf

  2. Include the gem in your application:

require 'jruby_cxf'
...
  1. Download the Apache CXF distribution.

  2. Add Apache CXF's libraries to the Java classpath before running your application: jruby -J-cp "/apache-cxf-[version]/lib/*" your_webservice.rb

API Usage

WebServiceServlet

A class must include CXF::WebServiceServlet for it to become a Web Service:

class MyWebService
    include CXF::WebServiceServlet
    
    ...
end

WebServiceServlet transforms your class into a Java servlet so any servlet container (e.g., Apache Tomcat, Jetty, JBoss AS) can load an instance of the class.

The default servlet path is the root path but it can be changed by passing a path to the class's constructor:

...
my_web_service = MyWebService.new('/my-webservice')

# using Jetty 8 to publish Web Service
server = org.eclipse.jetty.server.Server.new(8080)
contexts = org.eclipse.jetty.server.handler.ContextHandlerCollection.new
server.set_handler(contexts)
rootContext = org.eclipse.jetty.servlet.ServletContextHandler.new(contexts, "/")
rootContext.addServlet(org.eclipse.jetty.servlet.ServletHolder.new(my_web_service), "/*")
server.start

The module provides the following methods to the class:

expose(name, signature, options = {})

  • name - Name of method to be published as a Web Service operation

  • signature - Map of method's expected parameters and return type:

    • expected => Sequence of key-value pairs where each pair corresponds to a method parameter. The key represents the type element name that is shown in the WSDL. The value represents the parameter's expected type.
    • returns => Expected object type returned by the method.
  • options - Map of options

    • label => Name given to the corresponding operation XML element in the WSDL. The default value is the name of the Ruby method.
    • out_parameter_name => Element name of the return value.
    • response_wrapper_name => Response wrapper element name.
Example
class Calculator
  include CXF::WebServiceServlet

  expose :add, {:expects => [{:a => :int}, {:b => :int}], :returns => :int}, :label => :Add
  expose :divide, {:expects => [{:a => :int}, {:b => :int}], :returns => :float}, :label => :Divide

  def add(a, b)
    return a + b
  end
  
  def divide(a, b)
    return a.to_f / b.to_f
  end
end

####service_name(service_name)

  • service_name - Service name of the Web Service. The default value is the name of the Ruby class + Service.
Example
class Calculator
  include CXF::WebServiceServlet

  service_name: :CalculatorService

  ...
end

####service_namespace(service_namespace)

  • service_namepace - Service's target namespace. The default value is http://rubjobj/.
Example
class Calculator
  include CXF::WebServiceServlet

  service_namespace: 'http://jruby-cxf.org'

  ...
end

####endpoint_name(endpoint_name)

  • endpoint_name - Service's port name.
Example
class Calculator
  include CXF::WebServiceServlet

  endpoint_name: 'ExamplePort'

  ...
end

ComplexType

An exposed method can have a parameter or return complex type. The class implementing the complex type must include CXF::ComplexType:

class MyComplexType
   include CXF::ComplexType
   ...
end

class MyWebService
   include CXF::WebServiceServlet
   
   expose :foo, {:expects => [{:param => :MyComplexType}], :returns => :MyComplexType}
   ...
end   

ComplexType provides the following methods:

member(name, type, options = {})

A member behaves like an attr_accessor but with one important difference: attributes are typed.

  • name - Attribute name.

  • type - Attribute type.

  • options - Map of options

    • required => The minOccurs for the corresponding type element. True sets the value to 1. False sets the value to 0. Its default value is true.
    • label => Name given to the corresponding type element in the WSDL. The default value is the member name.
Example
class Person
   include CXF::ComplexType
	
   member :name, :string
   member :age, :int, :required => false
end

namespace(namespace)

  • namespace - Complex type's target namespace. The default value is http://rubjobj/.
Example
class Person
   include CXF::ComplexType
	
   ...

   namespace 'http://jruby-cxf.org'	
end	

Supported simple types

  • big_decimal
  • boolean
  • byte
  • datetime
  • double
  • float
  • long
  • int
  • short
  • string
  • time

Support

Please report any bugs or desired improvements.

jruby-cxf's People

Contributors

cjmamo avatar

Stargazers

 avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar

Forkers

ruprict mediasp

jruby-cxf's Issues

SOAPAction http header causes:: The given SOAPAction {{HEADER}} does not match an operation.

Server hates client(savon). Errors Below

Server

Dir[Dir.pwd + "/apache-cxf-2.7.12/lib/*.jar"].each{|jar| require jar}
require 'rubygems'
require 'bundler/setup'
require 'jruby_cxf'

class Calculator
  include CXF::WebServiceServlet

  expose :add, {:expects => [{:a => :int}, {:b => :int}], :returns => :int}, :label => :Add
  expose :divide, {:expects => [{:a => :int}, {:b => :int}], :returns => :float}, :label => :Divide

  def add(a, b)
    return a + b
  end

  def divide(a, b)
    return a.to_f / b.to_f
  end
end
# Servlet path defaults to '/' if no argument is passed to the constructor
calculator = Calculator.new('/calculator')

# using Jetty 8 to publish Web Service
server = org.eclipse.jetty.server.Server.new(8080)
contexts = org.eclipse.jetty.server.handler.ContextHandlerCollection.new
server.set_handler(contexts)
rootContext = org.eclipse.jetty.servlet.ServletContextHandler.new(contexts, "/")
rootContext.addServlet(org.eclipse.jetty.servlet.ServletHolder.new(calculator), "/*")
server.start

ERROR

WARNING: Interceptor for {http://rubyobj/}Calculator#{http://rubyobj/}Add has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: The given SOAPAction Add does not match an operation.
    at org.apache.cxf.binding.soap.interceptor.SoapActionInInterceptor$SoapActionInAttemptTwoInterceptor.handleMessage(SoapActionInInterceptor.java:243)
    at org.apache.cxf.binding.soap.interceptor.SoapActionInInterceptor$SoapActionInAttemptTwoInterceptor.handleMessage(SoapActionInInterceptor.java:221)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
    at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
    at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:241)
    at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:248)
    at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:222)
    at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:153)
    at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:171)
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:286)
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:206)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:595)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.jruby.javasupport.JavaMethod.invokeDirectWithExceptionHandling(JavaMethod.java:470)
    at org.jruby.javasupport.JavaMethod.tryProxyInvocation(JavaMethod.java:641)
    at org.jruby.javasupport.JavaMethod.invokeDirect(JavaMethod.java:325)
    at org.jruby.java.invokers.InstanceMethodInvoker.call(InstanceMethodInvoker.java:71)
    at org.jruby.java.invokers.InstanceMethodInvoker.call(InstanceMethodInvoker.java:142)
    at org.jruby.RubyClass.finvoke(RubyClass.java:586)
    at org.jruby.RubyBasicObject.send19(RubyBasicObject.java:1513)
    at org.jruby.RubyKernel.send19(RubyKernel.java:2237)
    at org.jruby.RubyKernel$INVOKER$s$send19.call(RubyKernel$INVOKER$s$send19.gen)
    at org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:245)
    at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:251)
    at org.jruby.ast.CallSpecialArgBlockPassNode.interpret(CallSpecialArgBlockPassNode.java:68)
    at org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
    at org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:74)
    at org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:112)
    at org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:164)
    at org.jruby.runtime.Helpers$MethodMissingMethod.call(Helpers.java:452)
    at org.jruby.gen.InterfaceImpl1402562827.service(org/jruby/gen/InterfaceImpl1402562827.gen:13)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:503)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:429)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:255)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
    at org.eclipse.jetty.server.Server.handle(Server.java:370)
    at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:494)
    at org.eclipse.jetty.server.AbstractHttpConnection.content(AbstractHttpConnection.java:982)
    at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.content(AbstractHttpConnection.java:1043)
    at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:865)
    at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:240)
    at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:696)
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:53)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)
    at java.lang.Thread.run(Thread.java:695)
Sep 26, 2014 11:05:57 AM org.apache.cxf.phase.PhaseInterceptorChain doDefaultLogging
WARNING: Interceptor for {http://rubyobj/}Calculator#{http://rubyobj/}Add has thrown exception, unwinding now
org.apache.cxf.interceptor.Fault: The given SOAPAction Add does not match an operation.
    at org.apache.cxf.binding.soap.interceptor.SoapActionInInterceptor$SoapActionInAttemptTwoInterceptor.handleMessage(SoapActionInInterceptor.java:243)
    at org.apache.cxf.binding.soap.interceptor.SoapActionInInterceptor$SoapActionInAttemptTwoInterceptor.handleMessage(SoapActionInInterceptor.java:221)
    at org.apache.cxf.phase.PhaseInterceptorChain.doIntercept(PhaseInterceptorChain.java:272)
    at org.apache.cxf.transport.ChainInitiationObserver.onMessage(ChainInitiationObserver.java:121)
    at org.apache.cxf.transport.http.AbstractHTTPDestination.invoke(AbstractHTTPDestination.java:241)
    at org.apache.cxf.transport.servlet.ServletController.invokeDestination(ServletController.java:248)
    at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:222)
    at org.apache.cxf.transport.servlet.ServletController.invoke(ServletController.java:153)
    at org.apache.cxf.transport.servlet.CXFNonSpringServlet.invoke(CXFNonSpringServlet.java:171)
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.handleRequest(AbstractHTTPServlet.java:286)
    at org.apache.cxf.transport.servlet.AbstractHTTPServlet.doPost(AbstractHTTPServlet.java:206)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:595)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.jruby.javasupport.JavaMethod.invokeDirectWithExceptionHandling(JavaMethod.java:470)
    at org.jruby.javasupport.JavaMethod.tryProxyInvocation(JavaMethod.java:641)
    at org.jruby.javasupport.JavaMethod.invokeDirect(JavaMethod.java:325)
    at org.jruby.java.invokers.InstanceMethodInvoker.call(InstanceMethodInvoker.java:71)
    at org.jruby.java.invokers.InstanceMethodInvoker.call(InstanceMethodInvoker.java:142)
    at org.jruby.RubyClass.finvoke(RubyClass.java:586)
    at org.jruby.RubyBasicObject.send19(RubyBasicObject.java:1513)
    at org.jruby.RubyKernel.send19(RubyKernel.java:2237)
    at org.jruby.RubyKernel$INVOKER$s$send19.call(RubyKernel$INVOKER$s$send19.gen)
    at org.jruby.runtime.callsite.CachingCallSite.callBlock(CachingCallSite.java:245)
    at org.jruby.runtime.callsite.CachingCallSite.call(CachingCallSite.java:251)
    at org.jruby.ast.CallSpecialArgBlockPassNode.interpret(CallSpecialArgBlockPassNode.java:68)
    at org.jruby.ast.NewlineNode.interpret(NewlineNode.java:105)
    at org.jruby.evaluator.ASTInterpreter.INTERPRET_METHOD(ASTInterpreter.java:74)
    at org.jruby.internal.runtime.methods.InterpretedMethod.call(InterpretedMethod.java:112)
    at org.jruby.internal.runtime.methods.DefaultMethod.call(DefaultMethod.java:164)
    at org.jruby.runtime.Helpers$MethodMissingMethod.call(Helpers.java:452)
    at org.jruby.gen.InterfaceImpl1402562827.service(org/jruby/gen/InterfaceImpl1402562827.gen:13)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:684)
    at org.eclipse.jetty.servlet.ServletHandler.doHandle(ServletHandler.java:503)
    at org.eclipse.jetty.server.handler.ContextHandler.doHandle(ContextHandler.java:1086)
    at org.eclipse.jetty.servlet.ServletHandler.doScope(ServletHandler.java:429)
    at org.eclipse.jetty.server.handler.ContextHandler.doScope(ContextHandler.java:1020)
    at org.eclipse.jetty.server.handler.ScopedHandler.handle(ScopedHandler.java:135)
    at org.eclipse.jetty.server.handler.ContextHandlerCollection.handle(ContextHandlerCollection.java:255)
    at org.eclipse.jetty.server.handler.HandlerWrapper.handle(HandlerWrapper.java:116)
    at org.eclipse.jetty.server.Server.handle(Server.java:370)
    at org.eclipse.jetty.server.AbstractHttpConnection.handleRequest(AbstractHttpConnection.java:494)
    at org.eclipse.jetty.server.AbstractHttpConnection.content(AbstractHttpConnection.java:982)
    at org.eclipse.jetty.server.AbstractHttpConnection$RequestHandler.content(AbstractHttpConnection.java:1043)
    at org.eclipse.jetty.http.HttpParser.parseNext(HttpParser.java:865)
    at org.eclipse.jetty.http.HttpParser.parseAvailable(HttpParser.java:240)
    at org.eclipse.jetty.server.AsyncHttpConnection.handle(AsyncHttpConnection.java:82)
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint.handle(SelectChannelEndPoint.java:696)
    at org.eclipse.jetty.io.nio.SelectChannelEndPoint$1.run(SelectChannelEndPoint.java:53)
    at org.eclipse.jetty.util.thread.QueuedThreadPool.runJob(QueuedThreadPool.java:608)
    at org.eclipse.jetty.util.thread.QueuedThreadPool$3.run(QueuedThreadPool.java:543)
    at java.lang.Thread.run(Thread.java:695)

Client

require 'savon'
client = Savon.client(wsdl: 'http://localhost:8080/calculator?wsdl')
client.operations
# => [:divide, :add] 
response = client.call(:add)

ERROR

Savon::SOAPFault: (soap:Server) The given SOAPAction Add does not match an operation.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.