-
Notifications
You must be signed in to change notification settings - Fork 19
SOAP API
IMPORTANT NOTE : this set of tools doesn't pretend to solve SOAP problems everywhere and to respect any SOAP standards. It's just a tool to manipulate SOAP frames while making clients believe this is a real SOAP server. Anyone not happy with the way ersatz deals with SOAP is welcome to contribute more standard formats :D
It's an envelope with a body (header not managed yet) and the soapenv namespace...
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/">
<soapenv:Header/>
<soapenv:Body>
<yoursoapmessage>blabla</yoursoapmessage>
</soapenv:Body>
</soapenv:Envelope>
Note The Header is empty right and not used now because I don't need it yet...
Where there are errors, you can replace the content of the body by a fault having following format:
<soapenv:Fault>
<faultcode>{ fault.faultcode }</faultcode>
<faultstring>{ fault.faultstring }</faultstring>
<faultactor>{ fault.faultactor }</faultactor>
<detail><yourerrordetail>yourerror</yourerrordetail></detail>
</soapenv:Fault>
object ESOAP {
def toSOAP[T](t: T, ns: NamespaceBinding, base: xml.Elem)(implicit r: XMLWriter[T]): xml.NodeSeq
def toSOAP[T](t: T)(implicit r: XMLWriter[T], ns: NamespaceBinding): xml.NodeSeq
def toSOAP[T](t: T, ns: NamespaceBinding)(implicit r: XMLWriter[T]): xml.NodeSeq
def fromSOAP[T](x: xml.NodeSeq)(implicit r: XMLReader[T]): Option[T]
val SoapNS = xml.NamespaceBinding("soapenv", "http://schemas.xmlsoap.org/soap/envelope/", xml.TopScope)
}
- SoapNS is the default Namespace for Soap envelopes
-
toSOAP[T](t: T, ns: NamespaceBinding)
function allow managing custom namespace to your SOAP envelopes if required.
For ex:
implicit val ns = NamespaceBinding(
prefix = "test",
uri = "http://test.com/",
parent = ESOAP.SoapNS
)
val env = toSOAP(Foo(...))
assert( env == <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:test="http://test.com">...</soapenv> )
ESOAP.toSOAP(Foo(...))
is just an equivalent to EXML.toXML(SoapEnvelope(Foo(...)))
case class SoapEnvelope[T](t: T)(implicit _namespace: NamespaceBinding = ESOAP.SoapNS) {
def namespace = _namespace
}
Note namespace is implicit and by default set to default Soap namespace. But it means that you can define your own implicit namespace in your scope and it will be used in the SoapEnvelope
case class SoapFault[T](
faultcode: String,
faultstring: String,
faultactor: String,
detail: T
)
A text code used to indicate a class of errors. The possible values are standardized and defined in SoapFault object:
object SoapFault {
// Found an invalid namespace for the SOAP Envelope element
val FAULTCODE_VERSION_MISMATCH = "SOAP-ENV:VersionMismatch"
// An immediate child element of the Header element, with the mustUnderstand attribute set to "1", was not understood
val FAULTCODE_MUST_UNDERSTAND = "SOAP-ENV:MustUnderstand"
// The message was incorrectly formed or contained incorrect information
val FAULTCODE_CLIENT = "SOAP-ENV:Client"
// There was a problem with the server so the message could not proceed
val FAULTCODE_SERVER = "SOAP-ENV:Server"
}
A text message explaining the error
A text string indicating who caused the fault. This is useful if the SOAP message travels through several nodes in the SOAP message path, and the client needs to know which node caused the error. A node that does not act as the ultimate destination must include a faultActor element.
An element used to carry application-specific error messages. The detail element can contain child elements, called detail entries. Naturally, you must provide the implicit XMLReader[T]/XMLWriter[T]
To generate a SOAPFault frame, you can simply do:
implicit FooErreurFormatter extends XMLFormatter[FooErreur] {
...
}
ESOAP.toSoap(
SoapFault(
faultcode = SoapFault.FAULTCODE_CLIENT,
faultstring = "invalid",
faultactor = "actor",
detail = FooErreur(1, "erreur")
)
)
This provides default XML reader/writer for SoapEnvelope[T]
This provides default XML reader/writer for SoapFault[T]