Web Services Tips, Hints and FAQs
Tip: How can I override the default XML serialization logic?
XML serialization is performed by objects called 'serializers'. Developers can supply custom serializers that replace the default serialization logic.
| container config |
container := SstWSContainer containerNamed: 'MyContainer'.
config := container serializationManager serializationConfigurationNamed:
SstSoapConstants::SstSoapDefaultEnvelopeNamespace.
config serializer: MyCustomSerializer current.
Alternatively, the serialization configuration itself can be replaced.
| container |
container := SstWSContainer containerNamed: 'MyContainer'.
container serializationManager
addSerializationConfiguration: AbtXmlSerializationConfiguration newSoapConfiguration
named: SstSoapConstants::SstSoapDefaultEnvelopeNamespace.
-------------------------------
How can I disable/enable SOAP multi-ref serialization?
By default, SOAP encoded messages are constructed using the serialized named SstSoapOutputSerializer. This serializer causes all complex SOAP messages to be encoded as SOAP multi-refs. Notice that the serialization configuration is referenced using the SOAP encoding namespace.
| container config |
container := SstWSContainer containerNamed: 'MyContainer'.
config := container serializationManager serializationConfigurationNamed:
SstSoapConstants::SstSoapDefaultEncodingNamespace.
config serializer: AbtXmlSchemaOutputSerializer current.
-------------------------------
How can I supply custom deserializers to provide custom logic for mapping XML into objects?
Mapping parsed XML into Smalltalk model objects is performed by objects called 'deserializers'. Developers can supply custom deserializers to enhance default mapping behavior. Custom deserializers can be created and set in deserialization configurations.
| container config |
container := SstWSContainer containerNamed: 'MyContainer'.
config := container serializationManager
deserializationConfigurationNamed: SstSoapConstants::SstSoapDefaultEnvelopeNamespace.
config deserializer: AbtXmlSchemaInputDeserializer current.
Alternatively, the default SOAP deserialization configuration can be replaced as shown below.
| container config |
container := SstWSContainer containerNamed: 'MyContainer'.
config := AbtXmlDeserializationConfiguration newSoapConfiguration.
config deserializer: AbtXmlSchemaInputDeserializer current.
container serializationManager
addDeserializationConfiguration: config
named: SstSoapConstants::SstSoapDefaultEnvelopeNamespace.
-------------------------------
How can I print incoming and outgoing SOAP messages on my Web services server?
The message handler chain can be modified to add code that dumps the contents of the SOAP message and response.
| factory pluggableHandler |
factory := ( SstWSContainer containerNamed: 'VastSampleServerContainer' ) handlerFactory.
pluggableHandler :=SstWSPluggableHandler new
invokeBlock: [ :anSstWSMessageContext | | message |
[
message := anSstWSMessageContext propertyNamed: ##wsTransportMessageRequest.
AbtXmlUtility logError: 'Request->'.
AbtXmlUtility logError: message header debugPrintString.
AbtXmlUtility logError: message contents asString.
AbtXmlUtility logError: ''.
AbtXmlUtility logError: 'Response->'.
" NOTE: The output message is not stored in the message context. "
AbtXmlUtility logError:
(anSstWSMessageContext container serializationManager
serialize: anSstWSMessageContext currentMessage
context: anSstWSMessageContext )] fork
].
factory
register: pluggableHandler
named: 'wsHttpServerResponseHandler'
inNamespace: factory globalNamespace
To disable the tracing code, execute the snippet below:
| factory |
factory := ( SstWSContainer containerNamed: 'VastSampleServerContainer' ) handlerFactory.
factory
register: SstWSNoOperationHandler default
named: 'wsHttpServerResponseHandler' inNamespace: factory globalNamespace
-------------------------------
How can I print incoming and outgoing SOAP messages on my Web services client?
The message handler chain can be modified to add code that dumps the contents of the SOAP message and response.
| factory pluggableHandler |
factory := ( SstWSContainer containerNamed: 'VastSampleClientContainer' ) handlerFactory.
pluggableHandler :=SstWSPluggableHandler new
invokeBlock: [ :anSstWSMessageContext | | message |
[
message := anSstWSMessageContext propertyNamed: ##wsTransportMessageRequest.
AbtXmlUtility logError: 'Request->'.
AbtXmlUtility logError: message asString.
AbtXmlUtility logError: ''.
AbtXmlUtility logError: 'Response->'.
" NOTE: The output message is not stored in the message context. "
message := anSstWSMessageContext propertyNamed: ##wsTransportMessageResponse.
AbtXmlUtility logError: message header debugPrintString.
btXmlUtility logError: message contents asString ] fork
].
factory
register: pluggableHandler
named: 'wsHttpClientResponseHandler' inNamespace: factory globalNamespace
To disable the tracing code, execute the snippet below:
| factory |
factory := ( SstWSContainer containerNamed: 'VastSampleClientContainer' ) handlerFactory.
factory
register: SstWSNoOperationHandler default
named: 'wsHttpClientResponseHandler' inNamespace: factory globalNamespace
-------------------------------
How can I clean up the sockets and active HTTP servers in my image?
The script below shuts down all active HTTP servers, and terminates all active sockets.
[true] ensure: ["Stop a running system and clean everything out"
SstHttpServletEngine allInstances
do: [:e | e shutDown. e clear. e become: nil].
SstHttpServer allInstances
do: [:e | e shutDown. e clear. e become: nil].
Processor allProcesses
do: [:s | (s == UIProcess currentUI) ifFalse: [s basicTerminate]].
Processor reschedule.
SstApplicationContext clearAll.
SciSocketManager default closeAllSockets.]
-------------------------------
How does VAST default serializer determine the XML schema type for an object that is defined as 'anyType'?
The algorithm for processing 'anyType' and for processing 'subtypes' is very similar.
A new mapping spec is introduced (contained in 'abtvast.map') to represent the Smalltalk namespace. The new mapping spec is intended to describe how Smalltalk objects should map to XML schema types. For typical mapping specs, it is possible to have multiple types map to the same object; therefore, determination of a schema type from an object instance is ambiguous. The Smalltalk namespace mappings remove ambiguity because each object maps to a single schema type.
For many cases, it is not necessary to refer to the Smalltalk mapping spec in order to determine a proper type mapping. The Smalltalk namespace exists strictly to remove ambiguity when the same class can map to multiple types.
When trying to determine the 'actual' type for an object, VAST does the following:
•Check the schema of the base schema type to see if there is a more specialized type that matches the class name of the object being serialized.
•Try to find a mapping for the class name of the serialized object and use the mapping to determine the actual schema type. The mapping is searched for in:
•Smalltalk mapping namespace
•Base type namespace
•All other visible namespaces (namespaces visible at that point in serialization of the object)
For types other than anyType, if no specialized type is found, the baseType is assumed to be the serialization type.
For an anyType, if no specialized type is found, a type definition is constructed based on the class shape. The type is created in the "VA Smalltalk" namespace. The "Smalltalk" namespace is settable in the serialization configuration. The default value is urn:Vast and is globally settable in the pool variable AbtXmlConstants::AbtXmlSmalltalkNamespace.
-------------------------------
How can I disable validation during WSDL parsing?
Execute the following Smalltalk expression:
AbtXmlObjectCache current
addDeserializationConfiguration:
(AbtXmlDeserializationConfiguration newWsdlConfiguration validate: false)
named: 'http://schemas.xmlsoap.org/wsdl/'.
-------------------------------
How can I enable code page conversion of SOAP messages during serialization?
Add an 'XmlDefaultEncoding' entry to the [Xml] stanza of your application's .ini file and set decodingEnabled to false in the AbtXmlConfiguration used by AbtXmlMappingParser.
[Xml]
DefaultResourceQualifier=D:\vast\b49\xml\
XmlDefaultEncoding=UTF-8
The value for this entry should be the target encoding for the serialized SOAP message. The VAST Web services support will always attempt to serialize SOAP messages using the specified encoding.
For less common encodings, it may be necessary to add a code page mapping using API in AbtXmlStreamConverter to map the specified encoding value to a valid code page supported by the platform. AbtXmlStreamConverter mapEncoding: 'UTF-8' toCodePage: 65001
-------------------------------
How can I deploy commonly used schemas to a Web services container?
The deployment descriptor contains a <schemaUrls> block for this purpose. Schemas that are imported by deployed WSDL documents are automatically deployed to the container and do not need to be included in the <schemaUrls> block of the deployment descriptor.
<schemaUrls>
<schemaUrl>http://schemas.xmlsoap.org/ws/2002/07/secext/</schemaUrl>
</schemaUrls>
Use the <schemaUrls> block to: - Specify XML schemas required to provide supplemental functionality (ie. SOAP 1.2, WS-Security ) - Override schemas that are already deployed to the global XML object cache (ie. WSDL, SOAP)
-------------------------------
How can I enable a VAST container to process SOAP 1.2 messages?
VAST Web services containers can be configured to enable processing of SOAP 1.2 messages. This is accomplished by deploying SOAP 1.2 schemas and mapping specifications to the server container. See the sample directory /samples/sstws/soap12/Readme.txt for additional information about configuring a Web services container for SOAP 1.2.
The same Web services container can be used to process SOAP 1.1 and SOAP 1.2 messages.
-------------------------------
How can I enable a VAST client service to send SOAP 1.2 messages?
VAST Web services client containers can be configured to enable processing of SOAP 1.2 messages. This is accomplished by deploying SOAP 1.2 schemas and mapping specifications to the client container. In addition, SstWSService instances contain accessors to allow the SOAP 1.2 namespace to be specified for outgoing SOAP messages.
| service |
service := (SstWSContainer containerNamed: 'MyContainer')
serviceManager serviceNamed: 'SstWSInsurancePolicyInterface'
inNamespace: 'http://www.SstWSInsurancePolicyInterface.com/SstWSInsurancePolicyInterface-impl'.
service sstSoapEnvelopeNamespace: SstSoap12Constants::SstSoap12EnvelopeNamespace.
See the sample directory /samples/sstws/soap12/Readme.txt for additional information about configuring a Web services container for SOAP 1.2.
-------------------------------
How can I configure client services to pass WS-Security information?
The schema (http://schemas.xmlsoap.org/ws/2002/07/secext/) must be managed by the serializationManager of the Web services container. This is accomplished by modifying the client deployment descriptor to include the required schema.
<schemaUrls>
<schemaUrl>http://schemas.xmlsoap.org/ws/2002/07/secext/</schemaUrl>
</schemaUrls>
Authorization credentials can be specified in the SstWSService that is being invoked causing those credentials to be passed automatically as part of the message. The SstWSService contains accessors for getting and setting HTTP authorization credentials (#sstAuthCredential:) as well as WS-Security username tokens (#sstUsernameToken:). See the sample directory /samples/sstws/ws_security/Readme.txt for additional information and examples.
-------------------------------
How can I specify a custom servlet for processing incoming service requests?
The default servlet for processing incoming Web services messages is SstWSServlet. Developers may provide their own custom servlet if more sophisticated rocessing is required. To enable an alternative servlet using the default http transport strategy, execute code like that shown below:
SstWSHttpNetworkTransportStrategy defaultServletClass: MyWebServicesServlet
-------------------------------
How can I make use of custom SST transports for invocation of remote service operations?
The container configuration supports transport mappings that are used to map url schemes to the registered SST transport schemes used for invocation.
The #urlScheme setting can specify a full URL name to enable special processing for a specific resource location, or the value can be a scheme prefix (ie. 'http' or https') for general cases.
The #transportScheme is the identifier for an SstTransport configuration that describes the details of the underlying communications protocol.
<transportMappings>
<transportMapping urlScheme="http" transportScheme="httpl" />
<transportMapping urlScheme="http://vasthost:63003" transportScheme="vasthost" />
<transportMapping urlScheme="https" transportScheme="testhttps" />
</transportMappings>
The code below accomplishes the same task:
| myContainer |
myContainer := SstWSContainer containerNamed: 'VastSampleClientContainer'.
myContainer configuration
mapUrlScheme: 'http' toTransportScheme: 'httpl' ;
mapUrlScheme: 'http://vasthost:63003' toTransportScheme: 'vasthost' ;
mapUrlScheme: 'https' toTransportScheme: 'testhttps'
SST transport schemes must be registered in class SstTransport prior to usage. See the class methods #serverTransportConfiguration and registerPluginConfigurations in SstHttpCommunications for an example of how transport configurations are created and registered.
-------------------------------
How can I map a Smalltalk Dictionary to XML?
The resource files 'sstaxis.map' and 'sstaxis.xsd' contain the rules required for mapping Smalltalk Dictionary objects to/from XML. Dictionaries are represented in XML as 'Map' elements in the namespace 'http://xml.apache.org/xml-soap'
-------------------------------
How can I Reset the Web Services Environment During Development?
Execute SstWSContainer’s class side method resetWebServicesDevelopmentEnvironment. The method can be useful in several scenarios such as a failed deployment, or a failed deserialization attempt.
In both these cases, schemas can be left in several caches which should be removed so that any modifications made to them will take effect during the next test. Schemas are cached in lookup tables with the namespace as a key. If you update a schema and its namespace exists in these caches as a key, the schema will not be updated or re-imported.
The method also clears all containers from SstWSContainer's cache and resets the secure socket registry.