2009-11-12 6 views
2

Est-il possible de créer une opération de service Web en utilisant des types Java primitifs ou de base lors de l'utilisation du Jaxb2Marschaller dans spring-ws? Par exemple, une méthode qui ressemble à ceci:Types Jaxb2Marshaller et primitifs

@Override 
@PayloadRoot(localPart = "AddTaskRequest", namespace = "http://example.com/examplews/") 
public long addTask(final Task task) throws AddTaskFault { 
// do something 
return 0; 
} 

J'utilise le plugin Maven pour générer l'interface et les classes de modèle de mon WSDL. Lorsque je tente d'appeler le webservice je reçois l'erreur suivante:

java.lang.IllegalStateException: Aucun adaptateur pour terminal [...]: Votre point final mettre en œuvre une interface prise en charge comme MessageHandler ou PayloadEndpoint

J'ai découvert que si je change la méthode que:

@Override 
@PayloadRoot(localPart = "AddTaskRequest", namespace = "http://example.com/examplews/") 
public JAXBElement<Long> addTask(final JAXBElement<Task> task) throws AddTaskFault { 
final ObjectFactory objectFactory = new ObjectFactory(); 
return objectFactory.createAddTaskResponse(0L); 
} 

Je suis capable de l'appeler - mais cette signature n'est pas compatible avec l'interface générée par le plugin Maven.

Que puis-je faire pour configurer spring-ws pour pouvoir utiliser le premier type d'implémentation ou pour dire à maven jaxws plugin de générer la seconde variante de l'interface?

MISE À JOUR: Mes entrées pertinentes de configuration printemps-ws ressembler à ça:

<bean id="marshaller" class="org.springframework.oxm.jaxb.Jaxb2Marshaller"> 
<property name="contextPath" value="com.example.examplews" /> 
</bean> 

<bean class="org.springframework.ws.server.endpoint.adapter.GenericMarshallingMethodEndpointAdapter"> 
<constructor-arg ref="marshaller" /> 
</bean> 

<bean class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping"> 
<property name="order" value="1" /> 
</bean> 
+0

Pouvez-vous poster votre configuration xml printemps? J'ai eu un problème similaire et je l'ai résolu à travers la configuration ... il y a un certain temps, mais si vous postez le vôtre, je peux vérifier ce que ma conf correcte était et afficher les différences. – laura

Répondre

4

Quand tente de correspondre Spring-WS un EndpointAdapter à un Endpoint, il vérifie que tous les paramètres de la méthode du point final, plus sa valeur de retour, sont des types connus à la Jaxb2Marshaller, et long ne sera pas. Conceptuellement, cela a du sens, puisque JAXB n'aurait aucune idée de comment transformer un long en XML sans plus d'informations (c'est là que JAXBElement entre).

Vous devez réaliser que Spring-WS est et non une implémentation JAX-WS, et ne fait pas semblant d'être. Vous ne pouvez pas vraiment vous attendre à prendre des artefacts générés par JAX-WS et vous attendre à ce qu'ils fonctionnent dans Spring_WS, bien que dans de nombreux cas Spring-WS soit assez flexible pour y faire face.

+0

Ok, alors quelle serait la meilleure façon d'utiliser le printemps ws avec une approche descendante? Je veux utiliser maven pour générer les classes nécessaires afin que je doive juste implémenter l'interface de service Web. –

+0

Je ne connais pas d'outil de génération qui puisse le faire, mais Spring-WS est très code-light, donc vous n'économiseriez pas beaucoup de frappe. – skaffman

+0

donc vous recommandons d'utiliser bottom up et juste écrire mon code mon interface de service Web? –

0

Voici tout ce qui est pertinent dans ma config car je ne peux pas vraiment dire ce que vous pourriez changer, ils sont plutôt différents et cela fait un an et demi que je l'ai fait.

<bean id="schemaCollection" 
     class="org.springframework.xml.xsd.commons.CommonsXsdSchemaCollection"> 
     <property name="xsds" value="/my.xsd" /> 
     <property name="inline" value="true" /> 
    </bean> 

    <bean id="marshallingEndpoint" 
     class="....EndpointImpl"> 
    </bean> 

    <oxm:jaxb2-marshaller id="marshaller" contextPath=".....schema" /> 

    <bean id="annotationMapping"  class="org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping"> 
     <property name="interceptors"> 
      <list> 
       <bean class="org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor" /> 
       <bean class="org.springframework.ws.soap.server.endpoint.interceptor.PayloadValidatingInterceptor"> 
        <property name="xsdSchemaCollection" 
         ref="schemaCollection" /> 
        <property name="validateRequest" value="true" /> 
        <property name="validateResponse" value="true" /> 
       </bean> 
      </list> 
     </property> 
     <property name="order" value="1" /> 
    </bean> 

    <sws:marshalling-endpoints /> 

Espérons que cela aide d'une certaine façon. La classe Endpoint a @Endpoint, les méthodes @PayloadRoot. Ils ne sont pas revenus longtemps, mais je n'ai pas non plus besoin d'envelopper ma classe dans le JAXBElement.

[modifier] namespaces

xmlns:oxm="http://www.springframework.org/schema/oxm" 
    xmlns:sws="http://www.springframework.org/schema/web-services" 

    xsi:schemaLocation=" 
     http://www.springframework.org/schema/oxm 
     http://www.springframework.org/schema/oxm/spring-oxm-1.5.xsd"> 
+0

merci, quels namespaces sont oxm et sws? –

Questions connexes