Diferencia entre revisiones de «Castor»

De Dos Ideas.
Saltar a: navegación, buscar
Línea 3: Línea 3:
 
Es un gran herramienta para utilizar con [[Spring Web Services]], ya que se complementa mejor que otros frameworks (por ejemplo, XStream) a las definiciones de wsdl con Namespaces.  
 
Es un gran herramienta para utilizar con [[Spring Web Services]], ya que se complementa mejor que otros frameworks (por ejemplo, XStream) a las definiciones de wsdl con Namespaces.  
  
 +
==Castor y Namespaces ==
 +
Cuando se utiliza castor para la transformación de respuestas que tienen elementos con varios namespaces, por ejemplo:
 +
 +
<code xml>
 +
<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
 +
        elementFormDefault="qualified"
 +
        targetNamespace="http://www.dosideas.com.ar/ws/schema/servicio1"
 +
        xmlns:tp="http://www.dosideas.com.ar/ws/schema/tiposPropios">
 +
       
 +
 +
    <xsd:import namespace="http://www.dosideas.com.ar/ws/schema/tiposPropios"
 +
schemaLocation="tiposPropios.xsd" />
 +
 +
    <xsd:element name="obtenerClientesRequest">
 +
        <xsd:complexType>
 +
            <xsd:all>
 +
                <xsd:element name="empresa" type="tp:empresa"/>
 +
            </xsd:all>
 +
        </xsd:complexType>
 +
    </xsd:element>
 +
 +
    <xsd:element name="obtenerClientesResponse">
 +
        <xsd:complexType>
 +
            <xsd:sequence>
 +
                <xsd:element  minOccurs="0" maxOccurs="unbounded" name="cliente" type="tp:cliente"/>
 +
            </xsd:sequence>
 +
        </xsd:complexType>
 +
    </xsd:element>
 +
 +
</code>
 +
 +
En el caso de este xsd una respuesta correcta sería:
 +
 +
<code xml>
 +
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://www.dosideas.com.ar/ws/schema/servicio1" xmlns:tp="http://www.dosideas.com.ar/ws/schema/tiposPropios">
 +
  <soapenv:Header/>
 +
  <soapenv:Body>
 +
      <ser:obtenerClientesResponse>
 +
              <ser:cliente>
 +
                      <tp:parametro1/>
 +
                      <tp:parametro2/>
 +
                      <tp:parametro3/>
 +
              </ser:cliente>
 +
              <ser:cliente>
 +
                      <tp:parametro1/>
 +
                      <tp:parametro2/>
 +
                      <tp:parametro3/>
 +
              </ser:cliente>
 +
      </ser:obtenerClientesResponse>
 +
  </soapenv:Body>
 +
</soapenv:Envelope>
 +
</code>
 +
 +
Con la configuración "normal" de castor, que sería la siguiente (para la respuesta):
 +
 +
<code xml>
 +
    <class name="com.dosideas.ObtenerClientesResponse">
 +
        <map-to xml="obtenerClientesResponse"
 +
        ns-prefix="ser"
 +
        ns-uri="http://www.dosideas.com.ar/ws/schema/servicio1" />
 +
 +
        <field name="clientes" type="com.dosideas.Cliente" collection="collection" >
 +
            <bind-xml name="cliente" node="element"/>
 +
        </field>
 +
    </class>
 +
 +
    <class name="com.dosideas.Cliente">
 +
        <map-to xml="cliente"
 +
        ns-prefix="tp"
 +
        ns-uri="http://www.dosideas.com.ar/ws/schema/tiposPropios"/>
 +
 +
        <field name="parametro1" type="string">
 +
            <bind-xml name="parametro1" node="element" />
 +
        </field>
 +
 +
        <field name="parametro2" type="string">
 +
            <bind-xml name="parametro2" node="element" />
 +
        </field>
 +
 +
        <field name="parametro3" type="string">
 +
            <bind-xml name="parametro3" node="element" />
 +
        </field>
 +
    </class>
 +
</code>
 +
 +
La respuesta resultante de esto sería:
 +
 +
<code xml>
 +
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"  >
 +
  <soapenv:Header/>
 +
  <soapenv:Body>
 +
      <ser:obtenerClientesResponse xmlns:ser="http://www.dosideas.com.ar/ws/schema/servicio1">
 +
              <tp:cliente xmlns:tp="http://www.dosideas.com.ar/ws/schema/tiposPropios">
 +
                      <tp:parametro1/>
 +
                      <tp:parametro2/>
 +
                      <tp:parametro3/>
 +
              </tp:cliente>
 +
              <tp:cliente>
 +
                      <tp:parametro1/>
 +
                      <tp:parametro2/>
 +
                      <tp:parametro3/>
 +
              </tp:cliente>
 +
      </ser:obtenerClientesResponse>
 +
  </soapenv:Body>
 +
</soapenv:Envelope>
 +
</code>
 +
 +
Como se puede ver, la respuesta formada por Castor difiere un poco en como debería ser la respuesta correcta y esto es tomado como una violación de formación de la respuesta.
 +
Una solución '''poco elegante''' para solucionar esto es modificar la configuración de Castor de la siguiente forma:
 +
 +
<code xml>
 +
    <class name="com.dosideas.ObtenerClientesResponse">
 +
        <map-to xml="obtenerClientesResponse"
 +
        ns-prefix="ser"
 +
        ns-uri="http://www.dosideas.com.ar/ws/schema/servicio1" />
 +
 +
        <field name="clientes" type="com.dosideas.Cliente" collection="collection" >
 +
            <bind-xml name="cliente" node="element" xmlns:ser="http://www.dosideas.com.ar/ws/schema/servicio1"/>
 +
        </field>
 +
    </class>
 +
 +
    <class name="com.dosideas.Cliente">
 +
        <map-to xml="cliente"/>
 +
 +
        <field name="parametro1" type="string" >
 +
            <bind-xml name="parametro1" node="element" xmlns:tp="http://www.dosideas.com.ar/ws/schema/tiposPropios"/>
 +
        </field>
 +
 +
        <field name="parametro2" type="string">
 +
            <bind-xml name="parametro2" node="element" xmlns:tp="http://www.dosideas.com.ar/ws/schema/tiposPropios"/>
 +
        </field>
 +
 +
        <field name="parametro3" type="string">
 +
            <bind-xml name="parametro3" node="element" xmlns:tp="http://www.dosideas.com.ar/ws/schema/tiposPropios"/>
 +
        </field>
 +
    </class>
 +
</code>
 +
 +
De esta forma, la respuesta que quedaría formada por Castor quedaría de la siguiente forma (la cual no queda muy prolija, pero funciona):
 +
 +
<code xml>
 +
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"  >
 +
  <soapenv:Header/>
 +
  <soapenv:Body>
 +
      <ser:obtenerClientesResponse xmlns:ser="http://www.dosideas.com.ar/ws/schema/servicio1">
 +
              <ns0:cliente xmlns:ns0="http://www.dosideas.com.ar/ws/schema/servicio1">
 +
                      <tp:parametro1 xmlns:tp="http://www.dosideas.com.ar/ws/schema/tiposPropios"/>
 +
                      <ns1:parametro2 xmlns:ns1="http://www.dosideas.com.ar/ws/schema/tiposPropios"/>
 +
                      <ns2:parametro3 xmlns:ns2="http://www.dosideas.com.ar/ws/schema/tiposPropios"/>
 +
              </ns0:cliente>
 +
              <ns3:cliente xmlns:ns3="http://www.dosideas.com.ar/ws/schema/servicio1>
 +
                      <ns4:parametro1 xmlns:ns4="http://www.dosideas.com.ar/ws/schema/tiposPropios"/>
 +
                      <ns5:parametro2 xmlns:ns5="http://www.dosideas.com.ar/ws/schema/tiposPropios"/>
 +
                      <ns6:parametro3 xmlns:ns6="http://www.dosideas.com.ar/ws/schema/tiposPropios"/>
 +
              </ns3:cliente>
 +
      </ser:obtenerClientesResponse>
 +
  </soapenv:Body>
 +
</soapenv:Envelope>
 +
</code>
  
 
== Ver También ==
 
== Ver También ==
 
[http://www.castor.org/ Sitio Oficial de Castor]
 
[http://www.castor.org/ Sitio Oficial de Castor]

Revisión del 20:28 28 jun 2010

Castor es un framework Open Source para Java, para transformaciones de Xml a Objetos Java y viceversa.

Es un gran herramienta para utilizar con Spring Web Services, ya que se complementa mejor que otros frameworks (por ejemplo, XStream) a las definiciones de wsdl con Namespaces.

Castor y Namespaces

Cuando se utiliza castor para la transformación de respuestas que tienen elementos con varios namespaces, por ejemplo:

<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"

       elementFormDefault="qualified"
       targetNamespace="http://www.dosideas.com.ar/ws/schema/servicio1"
       xmlns:tp="http://www.dosideas.com.ar/ws/schema/tiposPropios">
       
   <xsd:import namespace="http://www.dosideas.com.ar/ws/schema/tiposPropios"

schemaLocation="tiposPropios.xsd" />

   <xsd:element name="obtenerClientesRequest">
       <xsd:complexType>
           <xsd:all>
               <xsd:element name="empresa" type="tp:empresa"/>
           </xsd:all>
       </xsd:complexType>
   </xsd:element>
   <xsd:element name="obtenerClientesResponse">
       <xsd:complexType>
           <xsd:sequence>
               <xsd:element  minOccurs="0" maxOccurs="unbounded" name="cliente" type="tp:cliente"/>
           </xsd:sequence>
       </xsd:complexType>
   </xsd:element>

En el caso de este xsd una respuesta correcta sería:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://www.dosideas.com.ar/ws/schema/servicio1" xmlns:tp="http://www.dosideas.com.ar/ws/schema/tiposPropios">

  <soapenv:Header/>
  <soapenv:Body>
     <ser:obtenerClientesResponse>
             <ser:cliente>
                     <tp:parametro1/>
                     <tp:parametro2/>
                     <tp:parametro3/>
             </ser:cliente>
             <ser:cliente>
                     <tp:parametro1/>
                     <tp:parametro2/>
                     <tp:parametro3/>
             </ser:cliente>
     </ser:obtenerClientesResponse>
  </soapenv:Body>

</soapenv:Envelope>

Con la configuración "normal" de castor, que sería la siguiente (para la respuesta):

   <class name="com.dosideas.ObtenerClientesResponse">
       <map-to xml="obtenerClientesResponse"
       ns-prefix="ser"
       ns-uri="http://www.dosideas.com.ar/ws/schema/servicio1" />
       <field name="clientes" type="com.dosideas.Cliente" collection="collection" >
           <bind-xml name="cliente" node="element"/>
       </field>
   </class>
   <class name="com.dosideas.Cliente">
       <map-to xml="cliente"
       ns-prefix="tp"
       ns-uri="http://www.dosideas.com.ar/ws/schema/tiposPropios"/>
       <field name="parametro1" type="string">
           <bind-xml name="parametro1" node="element" />
       </field>
       <field name="parametro2" type="string">
           <bind-xml name="parametro2" node="element" />
       </field>
       <field name="parametro3" type="string">
           <bind-xml name="parametro3" node="element" />
       </field>
   </class>

La respuesta resultante de esto sería:

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" >

  <soapenv:Header/>
  <soapenv:Body>
     <ser:obtenerClientesResponse xmlns:ser="http://www.dosideas.com.ar/ws/schema/servicio1">
             <tp:cliente xmlns:tp="http://www.dosideas.com.ar/ws/schema/tiposPropios">
                     <tp:parametro1/>
                     <tp:parametro2/>
                     <tp:parametro3/>
             </tp:cliente>
             <tp:cliente>
                     <tp:parametro1/>
                     <tp:parametro2/>
                     <tp:parametro3/>
             </tp:cliente>
     </ser:obtenerClientesResponse>
  </soapenv:Body>

</soapenv:Envelope>

Como se puede ver, la respuesta formada por Castor difiere un poco en como debería ser la respuesta correcta y esto es tomado como una violación de formación de la respuesta. Una solución poco elegante para solucionar esto es modificar la configuración de Castor de la siguiente forma:

   <class name="com.dosideas.ObtenerClientesResponse">
       <map-to xml="obtenerClientesResponse"
       ns-prefix="ser"
       ns-uri="http://www.dosideas.com.ar/ws/schema/servicio1" />
       <field name="clientes" type="com.dosideas.Cliente" collection="collection" >
           <bind-xml name="cliente" node="element" xmlns:ser="http://www.dosideas.com.ar/ws/schema/servicio1"/>
       </field>
   </class>
   <class name="com.dosideas.Cliente">
       <map-to xml="cliente"/>
       <field name="parametro1" type="string" >
           <bind-xml name="parametro1" node="element" xmlns:tp="http://www.dosideas.com.ar/ws/schema/tiposPropios"/>
       </field>
       <field name="parametro2" type="string">
           <bind-xml name="parametro2" node="element" xmlns:tp="http://www.dosideas.com.ar/ws/schema/tiposPropios"/>
       </field>
       <field name="parametro3" type="string">
           <bind-xml name="parametro3" node="element" xmlns:tp="http://www.dosideas.com.ar/ws/schema/tiposPropios"/>
       </field>
   </class>

De esta forma, la respuesta que quedaría formada por Castor quedaría de la siguiente forma (la cual no queda muy prolija, pero funciona):

<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" >

  <soapenv:Header/>
  <soapenv:Body>
     <ser:obtenerClientesResponse xmlns:ser="http://www.dosideas.com.ar/ws/schema/servicio1">
             <ns0:cliente xmlns:ns0="http://www.dosideas.com.ar/ws/schema/servicio1">
                     <tp:parametro1 xmlns:tp="http://www.dosideas.com.ar/ws/schema/tiposPropios"/>
                     <ns1:parametro2 xmlns:ns1="http://www.dosideas.com.ar/ws/schema/tiposPropios"/>
                     <ns2:parametro3 xmlns:ns2="http://www.dosideas.com.ar/ws/schema/tiposPropios"/>
             </ns0:cliente>
             <ns3:cliente xmlns:ns3="http://www.dosideas.com.ar/ws/schema/servicio1>
                     <ns4:parametro1 xmlns:ns4="http://www.dosideas.com.ar/ws/schema/tiposPropios"/>
                     <ns5:parametro2 xmlns:ns5="http://www.dosideas.com.ar/ws/schema/tiposPropios"/>
                     <ns6:parametro3 xmlns:ns6="http://www.dosideas.com.ar/ws/schema/tiposPropios"/>
             </ns3:cliente>
     </ser:obtenerClientesResponse>
  </soapenv:Body>

</soapenv:Envelope>

Ver También

Sitio Oficial de Castor