558 lines
26 KiB
XML
558 lines
26 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<!--
|
|
/*
|
|
* Copyright 2002-2008 the original author or authors.
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
-->
|
|
<chapter version="5" xml:id="webservices"
|
|
xmlns="http://docbook.org/ns/docbook"
|
|
xmlns:ns6="http://www.w3.org/1999/xlink"
|
|
xmlns:ns5="http://www.w3.org/1998/Math/MathML"
|
|
xmlns:ns4="http://www.w3.org/1999/xhtml"
|
|
xmlns:ns3="http://www.w3.org/2000/svg"
|
|
xmlns:ns="http://docbook.org/ns/docbook">
|
|
<title>Web Services</title>
|
|
|
|
<sect1 xml:id="web-services-introduction">
|
|
<title>Introduction</title>
|
|
|
|
<para>While the out-of-the-box support for web services in .NET is
|
|
excellent, there are a few areas that the Spring.NET thought could use
|
|
some improvement. Spring adds the ability to perform dependency injection
|
|
on standard asmx web services. Spring's .NET Web Services support also
|
|
allows you to export a 'plain CLR object' as a .NET web service By "plain
|
|
CLR object" we mean classes that do not contain infrastructure specific
|
|
attributes, such as WebMethod. On the server side, Spring's .NET web
|
|
service exporters will automatically create a proxy that adds web service
|
|
attributes. On the client side you can use Spring IoC container to
|
|
configure a client side proxy that you generated with standard command
|
|
line tools. Additionally, Spring provides the functionality to create the
|
|
web service proxy dynamically at runtime (much like running the command
|
|
line tools but at runtime and without some of the tools quirks) and use
|
|
dependency injection to configure the resulting proxy class. On both the
|
|
server and client side, you can apply AOP advice to add behavior such as
|
|
logging, exception handling, etc. that is not easily encapsulated within
|
|
an inheritance hierarchy across the application.</para>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="server-side">
|
|
<title>Server-side</title>
|
|
|
|
<para>One thing that the Spring.NET team didn't like much is that we had
|
|
to have all these .asmx files lying around when all said files did was
|
|
specify which class to instantiate to handle web service requests.</para>
|
|
|
|
<para>Second, the Spring.NET team also wanted to be able to use the
|
|
Spring.NET IoC container to inject dependencies into our web service
|
|
instances. Typically, a web service will rely on other objects, service
|
|
objects for example, so being able to configure which service object
|
|
implementation to use is very useful.</para>
|
|
|
|
<para>Last, but not least, the Spring.NET team did not like the fact that
|
|
creating a web service is an implementation task. Most (although not all)
|
|
services are best implemented as normal classes that use coarse-grained
|
|
service interfaces, and the decision as to whether a particular service
|
|
should be exposed as a remote object, web service, or even an enterprise
|
|
(COM+) component, should only be a matter of configuration, and not
|
|
implementation.</para>
|
|
|
|
<para>An example using the web service exporter can be found in quickstart
|
|
example named 'calculator'. More information can be found here '<link
|
|
linkend="websvc-example">Web Services example</link>'.</para>
|
|
|
|
<sect2 xml:id="web-services-noasmx">
|
|
<title>Removing the need for .asmx files</title>
|
|
|
|
<para>Unlike web pages, which use <literal>.aspx</literal> files to
|
|
store presentation code, and code-behind classes for the logic, web
|
|
services are completely implemented within the code-behind class. This
|
|
means that .asmx files serve no useful purpose, and as such they should
|
|
neither be necessary nor indeed required at all.</para>
|
|
|
|
<para>Spring.NET allows application developers to expose existing web
|
|
services easily by registering a custom implementation of the
|
|
<literal>WebServiceHandlerFactory</literal> class and by creating a
|
|
standard Spring.NET object definition for the service.</para>
|
|
|
|
<para>By way of an example, consider the following web service...</para>
|
|
|
|
<programlisting language="csharp">
|
|
namespace MyComany.MyApp.Services
|
|
{
|
|
[WebService(Namespace="http://myCompany/services")]
|
|
public class HelloWorldService
|
|
{
|
|
[WebMethod]
|
|
public string HelloWorld()
|
|
{
|
|
return "Hello World!";
|
|
}
|
|
}
|
|
}
|
|
</programlisting>
|
|
|
|
<para>This is just a standard class that has methods decorated with the
|
|
<literal>WebMethod</literal> attribute and (at the class-level) the
|
|
<literal>WebService</literal> attribute. Application developers can
|
|
create this web service within Visual Studio just like any other
|
|
class.</para>
|
|
|
|
<para>All that one need to do in order to publish this web service
|
|
is:</para>
|
|
|
|
<para><emphasis> 1. Register the
|
|
<literal>Spring.Web.Services.WebServiceFactoryHandler</literal> as the
|
|
HTTP handler for <literal>*.asmx</literal> requests within one's
|
|
<literal>web.config</literal> file. </emphasis></para>
|
|
|
|
<programlisting language="myxml">
|
|
<system.web>
|
|
<httpHandlers>
|
|
<add verb="*" path="*.asmx" type="Spring.Web.Services.WebServiceHandlerFactory, Spring.Web"/>
|
|
</httpHandlers>
|
|
</system.web>
|
|
</programlisting>
|
|
|
|
<para>Of course, one can register any other extension as well, but
|
|
typically there is no need as Spring.NET's handler factory will behave
|
|
exactly the same as a standard handler factory if said handler factory
|
|
cannot find the object definition for the specified service name. In
|
|
that case the handler factory will simply look for an .asmx file.</para>
|
|
|
|
<para>If you are using IIS7 the following configuration is needed</para>
|
|
|
|
<programlisting language="myxml"><system.webServer>
|
|
<validation validateIntegratedModeConfiguration="false"/>
|
|
<handlers>
|
|
<add name="SpringWebServiceSupport" verb="*" path="*.asmx" type="Spring.Web.Services.WebServiceHandlerFactory, Spring.Web"/>
|
|
</handlers>
|
|
</system.webServer></programlisting>
|
|
|
|
<para><emphasis>2. Create an object definition for one's web
|
|
service.</emphasis></para>
|
|
|
|
<programlisting language="myxml"><object name="HelloWorld" type="MyComany.MyApp.Services.HelloWorldService, MyAssembly" abstract="true"/></programlisting>
|
|
|
|
<para>Note that one is not absolutely required to make the web service
|
|
object definition <literal>abstract</literal> (via the
|
|
<literal>abstract="true"</literal> attribute), but this is a recommended
|
|
best practice in order to avoid creating an unnecessary instance of the
|
|
service. Because the .NET infrastructure creates instances of the target
|
|
service object internally for each request, all Spring.NET needs to
|
|
provide is the <literal>System.Type</literal> of the service class,
|
|
which can be retrieved from the object definition even if it is marked
|
|
as <literal>abstract</literal>.</para>
|
|
|
|
<para>That's pretty much it as we can access this web service using the
|
|
value specified for the <literal>name</literal> attribute of the object
|
|
definition as the service name:</para>
|
|
|
|
<programlisting>http://localhost/MyWebApp/HelloWorld.asmx</programlisting>
|
|
</sect2>
|
|
|
|
<sect2 xml:id="web-services-di">
|
|
<title>Injecting dependencies into web services</title>
|
|
|
|
<para>For arguments sake, let's say that we want to change the
|
|
implementation of the <literal>HelloWorld</literal> method to make the
|
|
returned message configurable.</para>
|
|
|
|
<para>One way to do it would be to use some kind of message locator to
|
|
retrieve an appropriate message, but that locator needs to implemented.
|
|
Also, it would certainly be an odd architecture that used dependency
|
|
injection throughout the application to configure objects, but that
|
|
resorted to the service locator approach when dealing with web
|
|
services.</para>
|
|
|
|
<para>Ideally, one should be able to define a property for the message
|
|
within one's web service class and have Spring.NET inject the message
|
|
value into it:</para>
|
|
|
|
<programlisting language="csharp">
|
|
namespace MyApp.Services
|
|
{
|
|
public interface IHelloWorld
|
|
{
|
|
string HelloWorld();
|
|
}
|
|
|
|
[WebService(Namespace="http://myCompany/services")]
|
|
public class HelloWorldService : IHelloWorld
|
|
{
|
|
private string message;
|
|
public string Message
|
|
{
|
|
set { message = value; }
|
|
}
|
|
|
|
[WebMethod]
|
|
public string HelloWorld()
|
|
{
|
|
return this.message;
|
|
}
|
|
}
|
|
}
|
|
</programlisting>
|
|
|
|
<para>The problem with standard Spring.NET DI usage in this case is that
|
|
Spring.NET does not control the instantiation of the web service. This
|
|
happens deep in the internals of the .NET framework, thus making it
|
|
quite difficult to plug in the code that will perform the
|
|
configuration.</para>
|
|
|
|
<para>The solution is to create a dynamic server-side proxy that will
|
|
wrap the web service and configure it. That way, the .NET framework gets
|
|
a reference to a proxy type from Spring.NET and instantiates it. The
|
|
proxy then asks a Spring.NET application context for the actual web
|
|
service instance that will process requests.</para>
|
|
|
|
<para>This proxying requires that one export the web service explicitly
|
|
using the <literal>Spring.Web.Services.WebServiceExporter</literal>
|
|
class; in the specific case of this example, one must also not forget to
|
|
configure the <literal>Message</literal> property for said
|
|
service:</para>
|
|
|
|
<programlisting language="myxml">
|
|
<object id="HelloWorld" type="MyApp.Services.HelloWorldService, MyApp">
|
|
<property name="Message" value="Hello, World!"/>
|
|
</object>
|
|
|
|
<object id="HelloWorldExporter" type="Spring.Web.Services.WebServiceExporter, Spring.Web">
|
|
<property name="TargetName" value="HelloWorld"/>
|
|
</object>
|
|
</programlisting>
|
|
|
|
<para>The <literal>WebServiceExporter</literal> copies the existing web
|
|
service and method attribute values to the proxy implementation (if
|
|
indeed any are defined). Please note however that existing values can be
|
|
overridden by setting properties on the
|
|
<literal>WebServiceExporter</literal>.</para>
|
|
|
|
<tip>
|
|
<title>Interface Requirements</title>
|
|
|
|
<para>In order to support some advanced usage scenarios, such as the
|
|
ability to expose an AOP proxy as a web service (allowing the addition
|
|
of AOP advices to web service methods), Spring.NET requires those
|
|
objects that need to be exported as web services to implement a
|
|
(service) interface.</para>
|
|
|
|
<para>Only methods that belong to an interface will be exported by the
|
|
<literal>WebServiceExporter</literal>.</para>
|
|
</tip>
|
|
</sect2>
|
|
|
|
<sect2 xml:id="web-services-exporter">
|
|
<title>Exposing POCOs as Web Services</title>
|
|
|
|
<para>Now that we are generating a server-side proxy for the service,
|
|
there is really no need for it to have all the attributes that web
|
|
services need to have, such as <literal>WebMethod</literal>. Because
|
|
.NET infrastructure code never really sees the "real" service, those
|
|
attributes are redundant as the proxy needs to have them on its methods,
|
|
because that's what .NET deals with, but they are not necessary on the
|
|
target service's methods.</para>
|
|
|
|
<para>This means that we can safely remove the
|
|
<literal>WebService</literal> and <literal>WebMethod</literal> attribute
|
|
declarations from the service implementation, and what we are left with
|
|
is a plain old CLR object (a POCO). The example above would still work,
|
|
because the proxy generator will automatically add
|
|
<literal>WebMethod</literal> attributes to all methods of the exported
|
|
interfaces.</para>
|
|
|
|
<para>However, that is still not the ideal solution. You would lose
|
|
information that the optional <literal>WebService</literal> and
|
|
<literal>WebMethod</literal> attributes provide, such as service
|
|
namespace, description, transaction mode, etc. One way to keep those
|
|
values is to leave them within the service class and the proxy generator
|
|
will simply copy them to the proxy class instead of creating empty ones,
|
|
but that really does defeat the purpose.</para>
|
|
|
|
<para>To add specific attributes to the exported web service, you can
|
|
set all the necessary values within the definition of the service
|
|
exporter, like so...</para>
|
|
|
|
<programlisting language="myxml">
|
|
<object id="HelloWorldExporter" type="Spring.Web.Services.WebServiceExporter, Spring.Web">
|
|
<property name="TargetName" value="HelloWorld"/>
|
|
<property name="Namespace" value="http://myCompany/services"/>
|
|
<property name="Description" value="My exported HelloWorld web service"/>
|
|
<property name="MemberAttributes">
|
|
<dictionary>
|
|
<entry key="HelloWorld">
|
|
<object type="System.Web.Services.WebMethodAttribute, System.Web.Services">
|
|
<property name="Description" value="My Spring-configured HelloWorld method."/>
|
|
<property name="MessageName" value="ZdravoSvete"/>
|
|
</object>
|
|
</entry>
|
|
</dictionary>
|
|
</property>
|
|
</object>
|
|
|
|
// or, once configuration improvements are implemented...
|
|
<web:service targetName="HelloWorld" namespace="http://myCompany/services">
|
|
<description>My exported HelloWorld web service.</description>
|
|
<methods>
|
|
<method name="HelloWorld" messageName="ZdravoSvete">
|
|
<description>My Spring-configured HelloWorld method.</description>
|
|
</method>
|
|
</methods>
|
|
</web:service>
|
|
</programlisting>
|
|
|
|
<para>Based on the configuration above, Spring.NET will generate a web
|
|
service proxy for all the interfaces implemented by a target and add
|
|
attributes as necessary. This accomplishes the same goal while at the
|
|
same time moving web service metadata from implementation class to
|
|
configuration, which allows one to export pretty much
|
|
<emphasis>any</emphasis> class as a web service.</para>
|
|
|
|
<para>The WebServiceExporter also has a
|
|
<literal>TypeAttributes</literal> IList property for applying attributes
|
|
at the type level.<note>
|
|
<para>The attribute to confirms to the WSI basic profile 1.1 is not
|
|
added by default. This will be added in a future release. In the
|
|
meantime use the TypeAttributes IList property to add
|
|
<literal>[WebServiceBinding(ConformsTo=WsiProfiles.BasicProfile1_1)]</literal>
|
|
to the generated proxy.</para>
|
|
</note></para>
|
|
|
|
<para>One can also export only certain interfaces that a service class
|
|
implements by setting the <literal>Interfaces</literal> property of the
|
|
<literal>WebServiceExporter</literal>.</para>
|
|
|
|
<warning>
|
|
<title>Distributed Objects Warning</title>
|
|
|
|
<para>Distributed Objects Warning</para>
|
|
|
|
<para>Just because you <emphasis>can</emphasis> export any object as a
|
|
web service, doesn't mean that you <emphasis>should</emphasis>.
|
|
Distributed computing principles still apply and you need to make sure
|
|
that your services are not chatty and that arguments and return values
|
|
are Serializable.</para>
|
|
|
|
<para>You still need to exercise common sense when deciding whether to
|
|
use web services (or remoting in general) at all, or if local service
|
|
objects are all you need.</para>
|
|
</warning>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Exporting an AOP Proxy as a Web Service</title>
|
|
|
|
<para>It is often useful to be able to export an AOP proxy as a web
|
|
service. For example, consider the case where you have a service that is
|
|
wrapped with an AOP proxy that you want to access both locally and
|
|
remotely (as a web service). The local client would simply obtain a
|
|
reference to an AOP proxy directly, but any remote client needs to
|
|
obtain a reference to an exported web service proxy, that delegates
|
|
calls to an AOP proxy, that in turn delegates them to a target object
|
|
while applying any configured AOP advice.</para>
|
|
|
|
<para>Effecting this setup is actually fairly straightforward; because
|
|
an AOP proxy is an object just like any other object, all you need to do
|
|
is set the <literal>WebServiceExporter</literal>'s
|
|
<literal>TargetName</literal> property to the <literal>id</literal> (or
|
|
indeed the <literal>name</literal> or <literal>alias</literal>) of the
|
|
AOP proxy. The following code snippets show how to do this...</para>
|
|
|
|
<programlisting language="myxml">
|
|
<object id="DebugAdvice" type="MyApp.AOP.DebugAdvice, MyApp"/>
|
|
|
|
<object id="TimerAdvice" type="MyApp.AOP.TimerAdvice, MyApp"/>
|
|
|
|
<object id="MyService" type="MyApp.Services.MyService, MyApp"/>
|
|
|
|
<object id="MyServiceProxy" type="Spring.Aop.Framework.ProxyFactoryObject, Spring.Aop">
|
|
<property name="TargetName" value="MyService"/>
|
|
<property name="IsSingleton" value="true"/>
|
|
<property name="InterceptorNames">
|
|
<list>
|
|
<value>DebugAdvice</value>
|
|
<value>TimerAdvice</value>
|
|
</list>
|
|
</property>
|
|
</object>
|
|
|
|
<object id="MyServiceExporter" type="Spring.Web.Services.WebServiceExporter, Spring.Web">
|
|
<property name="TargetName" value="MyServiceProxy"/>
|
|
<property name="Name" value="MyService"/>
|
|
<property name="Namespace" value="http://myApp/webservices"/>
|
|
<property name="Description" value="My web service"/>
|
|
</object>
|
|
</programlisting>
|
|
|
|
<para>That's it as every call to the methods of the exported web service
|
|
will be intercepted by the target AOP proxy, which in turn will apply
|
|
the configured debugging and timing advice to it.</para>
|
|
</sect2>
|
|
</sect1>
|
|
|
|
<sect1 xml:id="client-side">
|
|
<title>Client-side</title>
|
|
|
|
<para>On the client side, the main objection the Spring.NET team has is
|
|
that client code becomes tied to a proxy <emphasis>class</emphasis>, and
|
|
not to a service <emphasis>interface</emphasis>. Unless you make the proxy
|
|
class implement the service interface manually, as described by Juval Lowy
|
|
in his book "Programming .NET Components", application code will be less
|
|
flexible and it becomes very difficult to plug in different service
|
|
implementation in the case when one decides to use a new and improved web
|
|
service implementation or a local service instead of a web service.</para>
|
|
|
|
<para>The goal for Spring.NET's web services support is to enable the easy
|
|
generation of client-side proxies that implement a specific service
|
|
interface.</para>
|
|
|
|
<sect2>
|
|
<title>Using VS.NET generated proxy</title>
|
|
|
|
<para>The problem with the web-service proxy classes that are generated
|
|
by VS.NET or the WSDL command line utility is that they don't implement
|
|
a service interface. This tightly couples client code with web services
|
|
and makes it impossible to change the implementation at a later date
|
|
without modifying and recompiling the client.</para>
|
|
|
|
<para>Spring.NET provides a simple <literal>IFactoryObject</literal>
|
|
implementation that will generate a <emphasis>"proxy for
|
|
proxy"</emphasis> (however obtuse that may sound). Basically, the
|
|
<literal>Spring.Web.Services.WebServiceProxyFactory</literal> class will
|
|
create a proxy for the VS.NET- / WSDL-generated proxy that implements a
|
|
specified service interface (thus solving the problem with the
|
|
web-service proxy classes mentioned in the preceding paragraph).</para>
|
|
|
|
<para>At this point, an example may well be more illustrative in
|
|
conveying what is happening; consider the following interface definition
|
|
that we wish to expose as a web service...</para>
|
|
|
|
<programlisting language="csharp">
|
|
namespace MyCompany.Services
|
|
{
|
|
public interface IHelloWorld
|
|
{
|
|
string HelloWorld();
|
|
}
|
|
}
|
|
</programlisting>
|
|
|
|
<para>In order to be able to reference a web service endpoint through
|
|
this interface, you need to add a definition similar to the example
|
|
shown below to your client's application context:</para>
|
|
|
|
<programlisting language="myxml">
|
|
<object id="HelloWorld" type="Spring.Web.Services.WebServiceProxyFactory, Spring.Services">
|
|
<property name="ProxyType" value="MyCompany.WebServices.HelloWorld, MyClientApp"/>
|
|
<property name="ServiceInterface" value="MyCompany.Services.IHelloWorld, MyServices"/>
|
|
</object>
|
|
</programlisting>
|
|
|
|
<para>What is important to notice is that the underlying implementation
|
|
class for the web service does not have to implement the same
|
|
<literal>IHelloWorld</literal> service interface... so long as matching
|
|
methods with compliant signatures exist (a kind of duck typing),
|
|
Spring.NET will be able to create a proxy and delegate method calls
|
|
appropriately. If a matching method cannot be found, the Spring.NET
|
|
infrastructure code will throw an exception.</para>
|
|
|
|
<para>That said, if you control both the client and the server it is
|
|
probably a good idea to make sure that the web service class on the
|
|
server implements the service interface, especially if you plan on
|
|
exporting it using Spring.NET's <literal>WebServiceExporter</literal>,
|
|
which requires an interface in order to work.</para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Generating proxies dynamically</title>
|
|
|
|
<para>The <literal>WebServiceProxyFactory</literal> can also dynamically
|
|
generate a web-service proxy. The XML object definition for this factory
|
|
object is shown below</para>
|
|
|
|
<programlisting language="myxml">
|
|
<object id="calculatorService" type="Spring.Web.Services.WebServiceProxyFactory, Spring.Services">
|
|
<property name="ServiceUri" value="http://myServer/Calculator/calculatorService.asmx"/>
|
|
<!--<property name="ServiceUri" value="file://~/calculatorService.wsdl"/>-->
|
|
<property name="ServiceInterface" value="Spring.Calculator.Interfaces.IAdvancedCalculator, Spring.Calculator.Contract"/>
|
|
<!-- Dependency injection on Factory's product : the proxy instance of type SoapHttpClientProtocol -->
|
|
<property name="ProductTemplate">
|
|
<object>
|
|
<property name="Timeout" value="10000" /> <!-- 10s -->
|
|
</object>
|
|
</property>
|
|
</object>
|
|
|
|
</programlisting>
|
|
|
|
<para>One use-case where this proxy is very useful is when dealing with
|
|
typed data sets through a web service. Leaving the pros and cons of this
|
|
approach aside, the current behavior of the proxy generator in .NET is
|
|
to create wrapper types for the typed dataset. This not only pollutes
|
|
the solution with extraneous classes but also results in multiple
|
|
wrapper types being created, one for each web service that uses the
|
|
typed dataset. This can quickly get confusing. The proxy created by
|
|
Spring allows you to reference you typed datasets directly, avoiding the
|
|
above mentioned issues.</para>
|
|
</sect2>
|
|
|
|
<sect2>
|
|
<title>Configuring the proxy instance</title>
|
|
|
|
<para>The <literal>WebServiceProxyFactory</literal> also implements the
|
|
interface,
|
|
<literal>Spring.Objects.Factory.IConfigurableFactoryObject</literal>,
|
|
allowing to specify configuration for the product that the
|
|
<literal>WebServiceProxyFactory</literal> creates. This is done by
|
|
specifying the ProductTemplate property. This is particularly useful for
|
|
securing the web service. An example is shown below.</para>
|
|
|
|
<programlisting language="myxml">
|
|
<object id="PublicarAltasWebService" type="Spring.Web.Services.WebServiceProxyFactory, Spring.Services">
|
|
<property name="ProxyType" value="My.WebService" />
|
|
<property name="ServiceInterface" value="My.IWebServiceInterface" />
|
|
<property name="ProductTemplate">
|
|
<object>
|
|
<!-- Configure the web service URL -->
|
|
<property name="Url" value="https://localhost/MyApp/webservice.jws" />
|
|
<!-- Configure the Username and password for the web service -->
|
|
<property name="Credentials">
|
|
<object type="System.Net.NetworkCredential, System">
|
|
<property name="UserName" value="user"/>
|
|
<property name="Password" value="password"/>
|
|
</object>
|
|
</property>
|
|
<!-- Configure client certificate for the web service -->
|
|
<property name="ClientCertificates">
|
|
<list>
|
|
<object id="MyCertificate" type="System.Security.Cryptography.X509Certificates.X509Certificate2, System">
|
|
<constructor-arg name="fileName" value="Certificate.p12" />
|
|
<constructor-arg name="password" value="notgoingtotellyou" />
|
|
</object>
|
|
</list>
|
|
</property>
|
|
</object>
|
|
</property>
|
|
</object>
|
|
</programlisting>
|
|
|
|
<para>For an example of how using SOAP headers for authentication using
|
|
the WebServiceExporter and WebServiceProxyFactory, refer to this <ulink
|
|
url="http://opensource.atlassian.com/confluence/spring/download/attachments/708/Spring.Examples.SoapHeader.rar?version=1">solution</ulink>
|
|
on our wiki.</para>
|
|
</sect2>
|
|
</sect1>
|
|
</chapter>
|