2011-02-12 10 views
8

Tengo un servicio web que estoy tratando de implementar con Spring y Jaxb. Ya tengo un puñado de servicios que funcionan usando ambos, pero este servicio en particular me está causando problemas debido al formato de la respuesta. En mi XSD, la respuesta se define como esto (aviso de que se trata de un solo elemento):JAXB + Spring WS: "Sin adaptador para punto final" mientras usa JAXBElement

<!-- Response definition --> 
<element name="ServiceResponse" type="Q1:Outcome"/> 


<!-- Outcome definition --> 
<complexType name="Outcome"> 
    <sequence> 
     <element name="ErrorCode"> 
      <simpleType> 
       <restriction base="string"> 
        <maxLength value="8"/> 
       </restriction> 
      </simpleType> 
     </element> 
     <element name="ErrorText"> 
      <simpleType> 
       <restriction base="string"> 
        <maxLength value="1000"/> 
       </restriction> 
      </simpleType> 
     </element> 
     <element name="DocumentId"> 
      <simpleType> 
       <restriction base="string"> 
        <maxLength value="30"/> 
       </restriction> 
      </simpleType> 
     </element> 
    </sequence> 
</complexType> 

Tengo un método de servicio que tiene este aspecto:

@PayloadRoot(localPart = SERVICE_REQUEST, namespace = NAMESPACE) 
public Outcome processFileRequest(ServiceRequest requestObject) 

termino con una excepción que tiene este aspecto:

java.lang.IllegalStateException: No hay ningún adaptador de punto final [pública dortman.xsd.objects.Outcome dortman.annotated.MyTestEndpoint.processFileRequest (dortman.xsd.objects.ServiceRequest)]: ¿su endpoint im ¿Admite una interfaz compatible como MessageHandler o Payload Endpoint?

Después de encontrar algunas publicaciones relacionadas en el foro de Spring y Stackoverflow, parece que los objetos devueltos deben tener la anotación XmlRootElement o estar envueltos en un JAXBElement. Para probar el primero, he cambiado la respuesta en el XSD para:

<!-- Response definition --> 
<element name="ServiceResponse"> 
    <complexType> 
     <sequence> 
      <element name="FileSize" type="long"/> 
     </sequence> 
    </complexType> 
</element> 

que funciona, como JAXB a continuación, genera una clase ServiceResponse que tiene la anotación XmlRootElement. Desafortunadamente, no necesariamente tengo la libertad de alterar el XSD, lo que significa que necesito buscar la otra opción. Así que lo intenté. Mi nuevo método de servicio es el siguiente:

@PayloadRoot(localPart = SERVICE_REQUEST, namespace = NAMESPACE) 
public JAXBElement<Outcome> processFileRequest(ServiceRequest requestObject) 

Y luego envolver mi objeto de retorno utilizando el método que se creó en ObjectFactory:

/** 
* Create an instance of {@link JAXBElement }{@code <}{@link Outcome }{@code >}} 
* 
*/ 
@XmlElementDecl(namespace = "http://www.dortman.com/MyTestService", name = "ServiceResponse") 
public JAXBElement<Outcome> createServiceResponse(Outcome value) { 
    return new JAXBElement<Outcome>(_ServiceResponse_QNAME, Outcome.class, null, value); 
} 

Cómo presento el servidor esperando esto para resolver el problema. Pero en lugar llego:

java.lang.IllegalStateException: No hay ningún adaptador de punto final [pública javax.xml.bind.JAXBElement dortman.annotated.MyTestEndpoint.processFileRequest (dortman.xsd.objects.ServiceRequest)]: ¿El su punto final implementa una interfaz compatible como MessageHandler o Payload Endpoint? en org.springframework.ws.server.MessageDispatcher.getEndpointAdapter (MessageDispatcher.java:283) en org.springframework.ws.server.MessageDispatcher.dispatch (MessageDispatcher.java:226) en org.springframework.ws.server. MessageDispatcher.receive (MessageDispatcher.java:169) en org.springframework.ws.transport.support.WebServiceMessageReceiverObjectSupport.handleConnection (WebServiceMessageReceiverObjectSupport.java:89) en org.springframework.ws.transport.http.WebServiceMessageReceiverHandlerAdapter.handle (WebServiceMessageReceiverHandlerAdapter.java:57) en org.springframework.ws.transport.http.MessageDispatcherServlet.doService (MessageDispatcherServlet.java:231) en weblogic.servlet.interna l.WebAppServletContext.execute (WebAppServletContext.java:2174) en weblogic.servlet.internal.ServletRequestImpl.run (ServletRequestImpl.java:1446) en weblogic.work.ExecuteThread.execute (ExecuteThread.java:201) en WebLogic. work.ExecuteThread.run (ExecuteThread.java:173)

Aparentemente no me impresionó el uso de JAXBElement.¿Alguien más ha encontrado este problema?

Mi fichero de configuración (que ya está trabajando con ~ 6 servicios web, es sólo que ninguno de ellos presentan esta variación XSD particular) contiene lo siguiente:

<!-- JAXB marshaller to be used by the annotated web services --> 
<bean class="org.springframework.ws.server.endpoint.adapter.MarshallingMethodEndpointAdapter"> 
<constructor-arg> 
<bean class="org.springframework.oxm.jaxb.Jaxb2Marshaller"> 
    <property name="contextPath" value="dortman.xsd.objects" /> 
    <property name="mtomEnabled" value="true"/> 
</bean> 
</constructor-arg> 
</bean> 

<bean id="messageFactory" class="org.springframework.ws.soap.axiom.AxiomSoapMessageFactory"> 
<property name="payloadCaching" value="true"></property> 
<property name="attachmentCaching" value="true"></property> 
</bean> 
+1

¿Cómo se ve tu configuración de contexto? ¿Cómo ha configurado el Marshaller JAXB allí? – skaffman

+0

Agregué esa información al final de la publicación. Ni siquiera pensé incluirlo, ya que parece ser suficiente para muchos otros servicios web. Creo que solo necesito dar un paso al frente y ver qué está haciendo Spring. – Dave

+0

Este hilo resolvió mi problema: [http://forum.springsource.org/showthread.php?69728-No-adapter-for-endpoint-Does-your-endpoint-implement-a-supported-interface-like-Messa] (http://forum.springsource.org/showthread.php?69728-No-adapter-for-endpoint-Does-your-endpoint-implement-a-supported-interface-like-Messa) – Carlos

Respuesta

0

Usted está viendo este error porque JAXB doesn' t saber qué nombre darle al elemento raíz cuando devuelve un objeto de tipo Resultado. Si está generando sus elementos del esquema, esperaría que tuviera una clase ServiceResponse que podría devolver en su lugar.

Si no puede obtener un objeto ServiceResponse, hubiera pensado que su enfoque de ajustar el resultado en un JAXBElement debería funcionar. ¿Ha comprobado que _ServiceResponse_QNAME está construido con el URI de espacio de nombres correcto?

+0

Sí, pensé lo mismo . El URI se ve bien. Afortunadamente, pronto me di cuenta de que si simplemente insertaba el elemento XSD, JAXB generaría clases que no necesitaran JAXBElement y el XML generado todavía se ajusta al XSD inalterado. Así que dejé de lado el problema. ;) – Dave

+0

@rjsang ¿Podría echar un vistazo a esta pregunta? ¡Gracias! http://stackoverflow.com/questions/19032798/spring-ws-jibx-no-adapter-for-endpoint-error – Spring

7

Es un problema relacionado con XSD, necesita corregir su XSD. Generalmente, cuando juegas con JAXB, este problema ocurrirá, necesitas definir la solicitud y la respuesta correctamente.

Se ha resuelto el problema. Por ejemplo, si el elemento de solicitud de entrada es 'InsertRequest' por lo que definir como

<xs:element name="InsertRequest"> 
<xs:annotation> 
<xs:documentation>Root element for Record Insert Request</xs:documentation> 
</xs:annotation> 
<xs:complexType> 
<xs:sequence> 
<xs:element name="GeneralDetails" type="tns:GenralDetailsType"></xs:element> 
<xs:element name="FullDetails" type="tns:FullDetailsType"></xs:element> 
</xs:sequence> 
</xs:complexType> 
</xs:element> 

Anteriormente se definió esto como se menciona a continuación: - por lo que cuando estoy creando granos JAXB siempre crea dos elementos de este, cuyo elemento (InsertRequest o InsertRequestType) necesidad de referirse en punto final, este era el problema.

<element name="InsertRequest" type="tns:InsertRequestType"></element> 


<complexType name="InsertRequestType"> 
<sequence> 
<element name="GeneralDetails" type="tns:GenralDetailsType"></element> 
<element name="FullDetails" type="tns:FullDetailsType"></element> 
</sequence> 
</complexType> 
1

Cuando tuve este problema, la respuesta resultó ser que me había olvidado de incluir la clase de elemento en la lista de classesToBeBound para la Jaxb2Marshaller primavera. Agregar estos a la lista solucionó el problema, pero nuestros elementos ya estaban configurados con un tipo complejo en línea.

Cuestiones relacionadas