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