PDA

View Full Version : Web service urls directly coupled to spring names, deliberate or error?


javajunky
11-07-2007, 11:51 AM
Hi guys,
I've been cheerfully using the WebServiceExporter for several months now, but I've recently realised that I made a bit of an architectural boo-boo, and have a need to de-couple the *url* for a web-service from its bean id/name.

Just as a recap, the current definition (grossly cut-down):

<object name="UserService_implementation" type="MyType/>
<object name="UserService" type="Spring.Web.Services.WebServiceExporter, Spring.Web>
<property name="TargetName" value="UserService_implementation"/>
</object>


Exposes a web-service of the form
http://myhost/UserService.asmx

Which is great, and exactly what I wanted! *However* just recently I've wanted (so that I could just explicitly and easily dependencies between 'services' [gah!] ) to do something like the following:


<object name="UserService" type="MyType/>
<object name="UserService_WebService" type="Spring.Web.Services.WebServiceExporter, Spring.Web>
<property name="TargetName" value="UserService"/>
</object>


Note the subtle differences between the two configurations, this [fairly obviously, given the last example], responds to a url of the form:
http://myhost/UserService_WebService.asmx
*HOWEVER* I would like to be able to expose the *bean* named 'UserService_WebService' as the service 'UserService.asmx'.

So, reading the documentation I see the 'Name' property, a-hah I read from the documentation:
The web service name. (defaults to the object id)

So I change this property to be the name I want the service to be exposed as ;) :

<object name="UserService" type="MyType/>
<object name="UserService_WebService" type="Spring.Web.Services.WebServiceExporter, Spring.Web>
<property name="TargetName" value="UserService"/>
<property name="Name" value="UserService"/>
</object>


But :( unfortunately the web-service is still 'exposed' as UserService_WebService.asmx, (however the WSDL etc. does take into account this 'Name' property.

On further [basic] examination I realise the 'issue' I'm seeing is because the WebServiceHandlerFactory directly maps the URL straight to the bean name and ignores the 'Name' property entirely e.g:

if (appContext.ContainsObjectDefinition(serviceName))

{

serviceType = appContext.GetType(serviceName);



// check if the type defines a Web Service

object[] wsAttribute = serviceType.GetCustomAttributes(typeof(WebServiceA ttribute), true);

if (wsAttribute.Length == 0)

{

serviceType = null;

}

}


Now I *get* why this is done (clearly its a fast way of doing it), but would it not be a lot more flexible to de-couple the url from the actual object definition name, and use appContext.GetObjectsOfType(typeof(WebServiceExpor ter)), then iterate over the 'Name' property of these objects ? .. I imagine there would be a penalty in terms of in-advertantly early-initialising these objects, so I guess you could do it on the definitions rather than the objects themselves, I'm ok here locally as I've actually re-implemented the WebServiceHandlerfActory locally to work properly with asynchronous web services as I got frustrated with running out of threads in IIS (stupid stupid thread-pool implementation), but just thought I'd ask the question in case a) My approach is suicide or b)Its a minor over-sight ?

Bruno Baia
11-08-2007, 01:44 AM
Hi,

I understand your problem, I also had some naming problems too because of that.
We will investigate a solution after 1.1 release, maybe using an optional pre-defined suffixe like ".asmx", ".ws" or ".webservice" in the object definition id/name.


You can also use aliases, but I gues u want to keep "UserService" name for the service implementation definition :

<object name="UserService_Implementation" type="MyType/>
<object name="UserService_WebService" type="Spring.Web.Services.WebServiceExporter, Spring.Web>
<property name="TargetName" value="UserService_Implementation"/>
<property name="Name" value="UserService"/>
</object>
<alias name="UserService_WebService" alias="UserService" />


I created an issue (http://opensource.atlassian.com/projects/spring/browse/SPRNET-762) about that.

- Bruno

javajunky
11-08-2007, 08:40 AM
Hi,
You can also use aliases, but I gues u want to keep "UserService" name for the service implementation definition :

That is my problem exactly, fwiw I've 'solved' it locally in my own WebServiceExporter class (which I had to use anyway as I execute most of my web service requests on long running threads in a seperate thread-pool). I can post this code if anyone's interested, but it isn't particularly pleasant !

Erich Eichinger
03-19-2008, 06:03 PM
Hi,

I extended the lookup algorithm which allows you to register your webservice for any arbitrary name.

Given a url "/child/script.asmx" the lookup occurs as follows:

1) try to lookup name "/child/script.asmx"
2) try to lookup name "script.asmx"
3) try to lookup name "script"

cheers,
Erich

javajunky
03-19-2008, 06:14 PM
Hi,

I extended the lookup algorithm which allows you to register your webservice for any arbitrary name.

cheers,
Erich

Fab I'll look forward to playing with it ;) Thanks Erich