views:

160

answers:

1

I have a spring webservice for which I have the schema in a directory as:

  • WebRoot/DataContract/person.xsd
  • WebRoot/DataContract/sub-person.xsd

Where sub-person.xsd is included in person.xsd that is:

in Person.xsd:

<xsd:import     namespace="http://www.mynamespace.org/xml/sub-person" 
                schemaLocation="sub-person.xsd"/>

I have defined the wsdl as:

<bean id="personserv" class="org.springframework.ws.wsdl.wsdl11.DefaultWsdl11Definition">   
  <property name="schemaCollection" ref="schemaCollection"/>                                               
  <property name="portTypeName" value="personserv"/>                                
  <property name="locationUri" value="/ws/personnelService/"/>                              
  <property name="targetNamespace" value="http://www.mynamespace.org/definitions"/&gt;       
</bean>

I can access the wsdl file using:

http://localhost:8080/myapp/ws/personnelService/personserv.wsdl

However, when making use of this wsdl the client can fetch person.xsd and cannot fetch sub-person.xsd giving an error failed to load

http://localhost:8080/myapp/ws/personnelService/sub-person.xsd

my question is how can I make sub-person.xsd available at the that URI location ?

I have also changed the location specified in person.xsd as:

<xsd:import     namespace="http://www.mynamespace.org/xml/sub-person" 
                schemaLocation="/DataContract/sub-person.xsd"/>

which the client then tried to find sub-person.xsd at:

http://localhost:8080/sub-person.xsd which isn't correct.

Another attempt was:

<xsd:import     namespace="http://www.mynamespace.org/xml/sub-person" 
                schemaLocation="DataContract/sub-person.xsd"/>

which the client then tried to find sub-person.xsd at:

http://localhost:8080/myapp/ws/personnelService/DataContract/sub-person.xsd

A: 

Spring-WS has this really nice facility for handling this, making use of the Apache XML Commons project:

<bean id="schemaCollection" class="org.springframework.xml.xsd.commons.CommonsXsdSchemaCollection">
    <property name="xsds">
        <list>
            <value>/DataContract/person.xsd</value>
            <value>/DataContract/sub-person.xsd</value>
        </list>
    </property>
    <property name="inline" value="true"/>
</bean>

The inline property is the key - it reads in each schema file, and whenever it finds an import or include reference from one to the other, it replaces the reference with the content of the referenced file.

The effect of this is that the output of the WSDL-generation controller is a single file with all schema information inlined within it, while still keeping the various schema files separate on the server. You then don't have to worry about if the client can chase the references and resolve them properly, since there are no references.

skaffman
Thanks that solved the issue.I had left out the 'inline' property from the schemaCollection, I am just not sure whether it would be a good idea to have one bulky wsdl file.
saky
@saky: Inlining the schema files can make quite a difference to performance
skaffman