You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-user@axis.apache.org by Jim Carlson <jc...@jnous.com> on 2003/02/20 10:05:48 UTC
Configuring Axis client within webapp
Hello,
I'm trying to determine the correct way to invoke a web service, from
within a servlet container context, which is itself running an Axis server.
My specific scenario is that I'm running Tomcat 4.1, and I have a
webapp which contains the Axis jars and server-config.wsdd. This webapp
should both publish and consume my web services. (In each case, the
other party is another, similar Tomcat/Axis server.) In addition, I
have some custom typemappings that need to work on both client and
server end.
I have no problem configuring the Axis server to publish my services
with the custom typemappings. However, I don't know how to create a
Service and a Call, from within the same webapp, which use the
typemappings from server-config.wsdd. It seems like there should be an
easy way to do this (without replicating config information anywhere).
I can get an instance of AxisServer by calling
AxisServletBase.getEngine(someOtherServlet). This AxisServlet has the
typemappings from server-config.wsdd. Next, I've tried the following
techniques:
new Service(axisServer.getConfig()).createCall();
new Service(axisServer.getClientEngine().getConfig()).createCall();
new
Service().setTypeMappingRegistry(axisServer.getTypeMappingRegistry());
... and some other permutations as well. In the first case,
Call.invoke() behaves very oddly, I think because it has server-side
handlers instead of client-side handlers. In both the first and second
cases, a subsequent check of Service.getTypeMappingRegistry() shows that
my custom mappings did not actually transfer over. In the third
case.... well here's the implementation of
Service.setTypeMappingRegistry() from axis/client/Service.java:
public void setTypeMappingRegistry(TypeMappingRegistry registry)
throws ServiceException {
}
A no-op. That was a fun surprise. Anyhow, I will continue digging
through the source, but I thought someone on this list would probably
already know the *correct* way to acheive this. Note that I am trying
to avoid having a second client.wsdd file, or programmatically copying
over the individual Mappings, because both of these techniques
unnecessarily replicate configuration data. I hope there is something
better.
Thanks!
Jim
Re: deserializer problem
Posted by Xavier Renard <Xa...@ulg.ac.be>.
Jue (Jacky) Shu wrote:
> hi there,
>
> in wsdd, change the qName to qname.
ok it works
thank you very much
Xavier
> ----- Original Message -----
> From: "Xavier Renard" <Xa...@ulg.ac.be>
> To: <ax...@ws.apache.org>
> Sent: Thursday, February 20, 2003 4:28 AM
> Subject: deserializer problem
>
>
>
>>Hi,
>>
>>I have just installed axis and did test the examples that come along.
>>It works perfectly.
>>Then I did try to return a simple bean to a client but I get the
>>following error with the deszerializer:
>>
>>org.xml.sax.SAXException: Deserializing parameter 'searchReturn': could
>>not find deserializer for type
>> at
>>org.apache.axis.message.RPCHandler.onStartChild(RPCHandler.java:297)
>> at
>>
>
> org.apache.axis.encoding.DeserializationContextImpl.startElement(Deserializa
> tionContextImpl.java:921)
>
>> at
>>
>
> org.apache.axis.message.SAX2EventRecorder.replay(SAX2EventRecorder.java:198)
>
>>
Re: deserializer problem
Posted by "Jue (Jacky) Shu" <ja...@hotmail.com>.
hi there,
in wsdd, change the qName to qname.
----- Original Message -----
From: "Xavier Renard" <Xa...@ulg.ac.be>
To: <ax...@ws.apache.org>
Sent: Thursday, February 20, 2003 4:28 AM
Subject: deserializer problem
> Hi,
>
> I have just installed axis and did test the examples that come along.
> It works perfectly.
> Then I did try to return a simple bean to a client but I get the
> following error with the deszerializer:
>
> org.xml.sax.SAXException: Deserializing parameter 'searchReturn': could
> not find deserializer for type
> at
> org.apache.axis.message.RPCHandler.onStartChild(RPCHandler.java:297)
> at
>
org.apache.axis.encoding.DeserializationContextImpl.startElement(Deserializa
tionContextImpl.java:921)
> at
>
org.apache.axis.message.SAX2EventRecorder.replay(SAX2EventRecorder.java:198)
>
>
> If i try tcpmon everything seems to be fine except maybe the type of the
> response in the scheam(i'm relatively new comer to axis and soap so i
> just can assume this :-)). And when I do list the services, I can see
> that the attribute qName is empty.Is it normal?
>
> I paste some code below.If someone could have a quick look or tell me
> what's wrong,it would very nice
>
> regards
>
> Xavier
>
>
> response (tcpmon)
> -----------------
>
> <?xml version="1.0" encoding="UTF-8"?>
> <soapenv:Envelope
> xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
> xmlns:xsd="http://www.w3.org/2001/XMLSchema"
> xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
> <soapenv:Body>
> <searchResponse
> soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
> <searchReturn href="#id0"/>
> </searchResponse>
> <multiRef id="id0" soapenc:root="0"
> soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
> xsi:type="" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
> <authors xsi:type="soapenc:Array" soapenc:arrayType="xsd:string[1]"
> xmlns:ns1="http://www.w3.org/2002/12/soap-encoding">
> <item>author</item>
> </authors>
> <isbn xsi:type="xsd:string">isbn</isbn>
> <title xsi:type="xsd:string">title</title>
> <id xsi:type="xsd:int">1</id>
> </multiRef>
> </soapenv:Body>
> </soapenv:Envelope>
>
>
> client
> ------
>
> Call call = (Call) service.createCall();
>
> QName qn = new QName("BookService","Book");
> BeanSerializerFactory serializer = new
BeanSerializerFactory(Book.class,qn);
>
> BeanDeserializerFactory deserializer = new
> BeanDeserializerFactory(Book.class,qn);
>
> call.registerTypeMapping(Book.class,qn,serializer,deserializer);
>
> try{
>
>
call.setTargetEndpointAddress("http://127.0.0.1:8089/axis/services/BookServi
ce");
> call.setOperationName("search");
> call.addParameter("arg",XMLType.XSD_STRING,ParameterMode.IN);
> call.setReturnType(qn); Book book=(Book)call.invoke(new
Object[]{"Xavier"});
> System.out.println(book.getTitle());
> }
> catch(AxisFault fault){
> System.out.println("Error "+fault.toString());
>
> }
>
> }
>
> wsdd
> ----
>
> <deployment xmlns="http://xml.apache.org/axis/wsdd/"
> xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
> <service name="BookService" provider="java:RPC">
> <parameter name="className" value="books.BookService"/>
> <parameter name="allowedMethods" value="search"/>
> <beanMapping qName="myNS:Book" xmlns:myNS="BookService"
> languageSpecificType="java:books.Book"/>
>
> </service>
> </deployment>
>
>
> Service classe
> --------------
>
> public class BookService{
> Book myBook;
>
> public BookService(){
> myBook = new Book();
> myBook.setId(1);
> myBook.setTitle("title");
> myBook.setIsbn("isbn");
> myBook.setAuthors(new String[]{"author"});
> }
> public Book search(String string){
> return myBook;
>
>
> service
> -------
> <service name="BookService" provider="java:RPC">
> <parameter name="allowedMethods" value="search"/>
> <parameter name="className" value="books.BookService"/>
> <beanMapping languageSpecificType="java:books.Book" qname=""/>
> </service>
>
deserializer problem
Posted by Xavier Renard <Xa...@ulg.ac.be>.
Hi,
I have just installed axis and did test the examples that come along.
It works perfectly.
Then I did try to return a simple bean to a client but I get the
following error with the deszerializer:
org.xml.sax.SAXException: Deserializing parameter 'searchReturn': could
not find deserializer for type
at
org.apache.axis.message.RPCHandler.onStartChild(RPCHandler.java:297)
at
org.apache.axis.encoding.DeserializationContextImpl.startElement(DeserializationContextImpl.java:921)
at
org.apache.axis.message.SAX2EventRecorder.replay(SAX2EventRecorder.java:198)
If i try tcpmon everything seems to be fine except maybe the type of the
response in the scheam(i'm relatively new comer to axis and soap so i
just can assume this :-)). And when I do list the services, I can see
that the attribute qName is empty.Is it normal?
I paste some code below.If someone could have a quick look or tell me
what's wrong,it would very nice
regards
Xavier
response (tcpmon)
-----------------
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<soapenv:Body>
<searchResponse
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">
<searchReturn href="#id0"/>
</searchResponse>
<multiRef id="id0" soapenc:root="0"
soapenv:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xsi:type="" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/">
<authors xsi:type="soapenc:Array" soapenc:arrayType="xsd:string[1]"
xmlns:ns1="http://www.w3.org/2002/12/soap-encoding">
<item>author</item>
</authors>
<isbn xsi:type="xsd:string">isbn</isbn>
<title xsi:type="xsd:string">title</title>
<id xsi:type="xsd:int">1</id>
</multiRef>
</soapenv:Body>
</soapenv:Envelope>
client
------
Call call = (Call) service.createCall();
QName qn = new QName("BookService","Book");
BeanSerializerFactory serializer = new BeanSerializerFactory(Book.class,qn);
BeanDeserializerFactory deserializer = new
BeanDeserializerFactory(Book.class,qn);
call.registerTypeMapping(Book.class,qn,serializer,deserializer);
try{
call.setTargetEndpointAddress("http://127.0.0.1:8089/axis/services/BookService");
call.setOperationName("search");
call.addParameter("arg",XMLType.XSD_STRING,ParameterMode.IN);
call.setReturnType(qn); Book book=(Book)call.invoke(new Object[]{"Xavier"});
System.out.println(book.getTitle());
}
catch(AxisFault fault){
System.out.println("Error "+fault.toString());
}
}
wsdd
----
<deployment xmlns="http://xml.apache.org/axis/wsdd/"
xmlns:java="http://xml.apache.org/axis/wsdd/providers/java">
<service name="BookService" provider="java:RPC">
<parameter name="className" value="books.BookService"/>
<parameter name="allowedMethods" value="search"/>
<beanMapping qName="myNS:Book" xmlns:myNS="BookService"
languageSpecificType="java:books.Book"/>
</service>
</deployment>
Service classe
--------------
public class BookService{
Book myBook;
public BookService(){
myBook = new Book();
myBook.setId(1);
myBook.setTitle("title");
myBook.setIsbn("isbn");
myBook.setAuthors(new String[]{"author"});
}
public Book search(String string){
return myBook;
service
-------
<service name="BookService" provider="java:RPC">
<parameter name="allowedMethods" value="search"/>
<parameter name="className" value="books.BookService"/>
<beanMapping languageSpecificType="java:books.Book" qname=""/>
</service>
REPOST: Configuring Axis client within webapp
Posted by Jim Carlson <jc...@jnous.com>.
Howdy,
No answer to my question yet. I'm trying to create a Axis client
Call object within an Axis web application (i.e., within the same
Servlet context). The tricky thing is that I have some custom server
configuration (typemappings/beanmappings) in the server-config.wsdd that
should affect the Call as well. This seems like a relatively common
scenario -- attempting to create a grid of Axis servers that publish and
consume each other's Web Services, while using the same <typeMappings>.
Here is a snippet that I currently use to get the job done:
EngineConfiguration config =
new SimpleProvider(axis.getClientEngine().getConfig()) {
public TypeMappingRegistry getTypeMappingRegistry() {
return axis.getTypeMappingRegistry();
}
};
sub.service = new Service(config);
That's not very straightforward, but it works. (See my earlier email
below for some alternate approaches that failed.) Perhaps this code
will incite someone to criticize me and provide a better solution.
Thanks!
Jim
p.s. If it turns out that the cleanest solution is to have a
client-config.wsdd file in the WEB-INF directory, then I suppose I could
factor out the <typemappings> into a third file, and include them as
entities -- how's that? (again, I'm trying to avoid config
redundancy/cruftiness.)
Jim Carlson wrote:
> Hello,
> I'm trying to determine the correct way to invoke a web service, from
> within a servlet container context, which is itself running an Axis server.
> My specific scenario is that I'm running Tomcat 4.1, and I have a
> webapp which contains the Axis jars and server-config.wsdd. This webapp
> should both publish and consume my web services. (In each case, the
> other party is another, similar Tomcat/Axis server.) In addition, I
> have some custom typemappings that need to work on both client and
> server end.
> I have no problem configuring the Axis server to publish my services
> with the custom typemappings. However, I don't know how to create a
> Service and a Call, from within the same webapp, which use the
> typemappings from server-config.wsdd. It seems like there should be an
> easy way to do this (without replicating config information anywhere).
> I can get an instance of AxisServer by calling
> AxisServletBase.getEngine(someOtherServlet). This AxisServlet has the
> typemappings from server-config.wsdd. Next, I've tried the following
> techniques:
>
> new Service(axisServer.getConfig()).createCall();
>
> new Service(axisServer.getClientEngine().getConfig()).createCall();
>
> new
> Service().setTypeMappingRegistry(axisServer.getTypeMappingRegistry());
>
> ... and some other permutations as well. In the first case,
> Call.invoke() behaves very oddly, I think because it has server-side
> handlers instead of client-side handlers. In both the first and second
> cases, a subsequent check of Service.getTypeMappingRegistry() shows that
> my custom mappings did not actually transfer over. In the third
> case.... well here's the implementation of
> Service.setTypeMappingRegistry() from axis/client/Service.java:
>
> public void setTypeMappingRegistry(TypeMappingRegistry registry)
> throws ServiceException {
> }
>
> A no-op. That was a fun surprise. Anyhow, I will continue digging
> through the source, but I thought someone on this list would probably
> already know the *correct* way to acheive this. Note that I am trying
> to avoid having a second client.wsdd file, or programmatically copying
> over the individual Mappings, because both of these techniques
> unnecessarily replicate configuration data. I hope there is something
> better.
>
>
> Thanks!
>
> Jim
>
>
Re: Configuring Axis client within webapp
Posted by Jim Carlson <jc...@jnous.com>.
Thanks,
However, my issue is not related to the classpath. It is related to
the <beanMapping> and <typeMapping> configuration elements in the wsdd
file. I need these to work identically in both server and client mode.
Jim
Phil Cornelius wrote:
> The ideal way is to have AXIS integrated into your app/web server. For
> example JBoss.Net 3.2 integrates AXIS 1.0 into the app server itself and
> so you can consume and publish web services without any classpath
> conflicts..
>
> A simple work around that I have used successfully is to use AXIS to
> publish and host my services and to use 'Apache SOAP' to call other
> remote web services from within your servlet context..
>
> You can use IBMs WSTK (bundled with WSAD) to generate an Apache SOAP
> proxy from the remote service's WSDL..
>
> works a treat
>
> Yours
> Phil
>
>
>
> On Thu, 2003-02-20 at 09:05, Jim Carlson wrote:
>
>>Hello,
>> I'm trying to determine the correct way to invoke a web service, from
>>within a servlet container context, which is itself running an Axis server.
>> My specific scenario is that I'm running Tomcat 4.1, and I have a
>>webapp which contains the Axis jars and server-config.wsdd. This webapp
>>should both publish and consume my web services. (In each case, the
>>other party is another, similar Tomcat/Axis server.) In addition, I
>>have some custom typemappings that need to work on both client and
>>server end.
>> I have no problem configuring the Axis server to publish my services
>>with the custom typemappings. However, I don't know how to create a
>>Service and a Call, from within the same webapp, which use the
>>typemappings from server-config.wsdd. It seems like there should be an
>>easy way to do this (without replicating config information anywhere).
>> I can get an instance of AxisServer by calling
>>AxisServletBase.getEngine(someOtherServlet). This AxisServlet has the
>>typemappings from server-config.wsdd. Next, I've tried the following
>>techniques:
>>
>> new Service(axisServer.getConfig()).createCall();
>>
>> new Service(axisServer.getClientEngine().getConfig()).createCall();
>>
>> new
>>Service().setTypeMappingRegistry(axisServer.getTypeMappingRegistry());
>>
>>... and some other permutations as well. In the first case,
>>Call.invoke() behaves very oddly, I think because it has server-side
>>handlers instead of client-side handlers. In both the first and second
>>cases, a subsequent check of Service.getTypeMappingRegistry() shows that
>>my custom mappings did not actually transfer over. In the third
>>case.... well here's the implementation of
>>Service.setTypeMappingRegistry() from axis/client/Service.java:
>>
>> public void setTypeMappingRegistry(TypeMappingRegistry registry)
>> throws ServiceException {
>> }
>>
>>A no-op. That was a fun surprise. Anyhow, I will continue digging
>>through the source, but I thought someone on this list would probably
>>already know the *correct* way to acheive this. Note that I am trying
>>to avoid having a second client.wsdd file, or programmatically copying
>>over the individual Mappings, because both of these techniques
>>unnecessarily replicate configuration data. I hope there is something
>>better.
>>
>>
>>Thanks!
>>
>>Jim
>
>
>
Re: Configuring Axis client within webapp
Posted by Phil Cornelius <ph...@computer.org>.
The ideal way is to have AXIS integrated into your app/web server. For
example JBoss.Net 3.2 integrates AXIS 1.0 into the app server itself and
so you can consume and publish web services without any classpath
conflicts..
A simple work around that I have used successfully is to use AXIS to
publish and host my services and to use 'Apache SOAP' to call other
remote web services from within your servlet context..
You can use IBMs WSTK (bundled with WSAD) to generate an Apache SOAP
proxy from the remote service's WSDL..
works a treat
Yours
Phil
On Thu, 2003-02-20 at 09:05, Jim Carlson wrote:
> Hello,
> I'm trying to determine the correct way to invoke a web service, from
> within a servlet container context, which is itself running an Axis server.
> My specific scenario is that I'm running Tomcat 4.1, and I have a
> webapp which contains the Axis jars and server-config.wsdd. This webapp
> should both publish and consume my web services. (In each case, the
> other party is another, similar Tomcat/Axis server.) In addition, I
> have some custom typemappings that need to work on both client and
> server end.
> I have no problem configuring the Axis server to publish my services
> with the custom typemappings. However, I don't know how to create a
> Service and a Call, from within the same webapp, which use the
> typemappings from server-config.wsdd. It seems like there should be an
> easy way to do this (without replicating config information anywhere).
> I can get an instance of AxisServer by calling
> AxisServletBase.getEngine(someOtherServlet). This AxisServlet has the
> typemappings from server-config.wsdd. Next, I've tried the following
> techniques:
>
> new Service(axisServer.getConfig()).createCall();
>
> new Service(axisServer.getClientEngine().getConfig()).createCall();
>
> new
> Service().setTypeMappingRegistry(axisServer.getTypeMappingRegistry());
>
> ... and some other permutations as well. In the first case,
> Call.invoke() behaves very oddly, I think because it has server-side
> handlers instead of client-side handlers. In both the first and second
> cases, a subsequent check of Service.getTypeMappingRegistry() shows that
> my custom mappings did not actually transfer over. In the third
> case.... well here's the implementation of
> Service.setTypeMappingRegistry() from axis/client/Service.java:
>
> public void setTypeMappingRegistry(TypeMappingRegistry registry)
> throws ServiceException {
> }
>
> A no-op. That was a fun surprise. Anyhow, I will continue digging
> through the source, but I thought someone on this list would probably
> already know the *correct* way to acheive this. Note that I am trying
> to avoid having a second client.wsdd file, or programmatically copying
> over the individual Mappings, because both of these techniques
> unnecessarily replicate configuration data. I hope there is something
> better.
>
>
> Thanks!
>
> Jim