2016-09-06 2 views
0

Für jede ausgehende Nachricht bietet Salesforce eine vollständige, eigenständige WSDL.Wie können mehrere Empfänger von SFDC Outbound Message im selben Spring-Service implementiert werden?

Die Implementierung eines Spring-Service für einen einzelnen ist einfach, mit jaxws-maven-plugin zum Generieren der Klassen und @Endpoint, @PayloadRoot usw., um den Endpunkt zu binden.

Mehrere Outbound-Nachrichten verwenden jedoch alle dieselben QNs (z. B. http://soap.sforce.com/2005/09/outbound:notifications oder urn:sobject.enterprise.soap.sforce.com:sObject) für unterschiedliche Strukturen und Typhierarchien.

Ich weiß how to map the same XML names to different handlers based on URL path.

Ich weiß, wie ein separates Paket für die generierten Klassen mit einer Bindungsdatei verwenden:

<?xml version="1.0" encoding="UTF-8"?> 
<jaxws:bindings 
    xmlns:jaxws="http://java.sun.com/xml/ns/jaxws" 
    xmlns:jaxb="http://java.sun.com/xml/ns/jaxb" 
    xmlns:xs="http://www.w3.org/2001/XMLSchema" 
    wsdlLocation="../wsdl/SFDC_Contact_Outbound_Msg.wsdl" 
    version="2.0"> 

    <jaxb:bindings node="//xs:schema[@targetNamespace='http://soap.sforce.com/2005/09/outbound']"> 
    <jaxb:schemaBindings> 
     <jaxb:package name="com.sforce.soap.outbound.contact"/> 
    </jaxb:schemaBindings> 
    </jaxb:bindings> 

    <jaxb:bindings node="//xs:schema[@targetNamespace='urn:sobject.enterprise.soap.sforce.com']"> 
    <jaxb:schemaBindings> 
     <jaxb:package name="com.sforce.soap.enterprise.sobject.contact"/> 
    </jaxb:schemaBindings> 
    </jaxb:bindings> 

</jaxws:bindings> 

Wenn jedoch die Jaxb2Marshaller aus dem generierten Code zu initialisieren versucht, es kann immer noch nicht die XML-Konflikte behandeln:

Ich möchte keine weiteren manuellen Schritte hinzufügen, wenn die SDFC-generierte WSDL ändert, außer die neuen Dateien ablegen.

Gibt es eine Möglichkeit, die Namespaces in package-info.java zu ändern, ohne die Quell-WSDL zu ändern?

Gibt es einen Weg zu leicht (d. H. Nicht mit einer separaten @Bean Methode für jeden) einen separaten Marshaller für jedes Paket erstellen, die alle dann hinzugefügt werden könnten, um die DefaultMethodEndpointAdapter?

Gibt es eine andere Möglichkeit, all diese Empfänger für ausgehende Nachrichten zu implementieren?

Antwort

0

Gibt es eine Möglichkeit, die Namespaces zu ändern?

Wenn dies der Fall wäre, würden sie nicht mit den Namespaces in der aktuellen Nachricht übereinstimmen, so dass sie nicht unmarshalbar wäre.

Gibt es eine Möglichkeit, einfach einen separaten Marshaller für jedes Paket zu erstellen?

Nun, hier ist ein Weg, es zu tun.

@PostConstruct 
public void marshallers() throws IOException { 
    List<String> types = Arrays.stream(applicationContext.getResources("classpath:com/sforce/soap/outbound/*")) 
     .map(Resource::getFilename) 
     .collect(Collectors.toList()); 

    for (String type : types) { 
    String beanName = "marshallingPayloadMethodProcessor_" + type; 
    Jaxb2Marshaller marshaller = new Jaxb2Marshaller(); 
    marshaller.setPackagesToScan(
     "com.sforce.soap.outbound." + type, 
     "com.sforce.soap.enterprise.sobject." + type 
    ); 

    try { 
     marshaller.afterPropertiesSet(); 
    } catch (Exception ex) { 
     throw new BeanInitializationException("Could not initialize bean " + beanName, ex); 
    } 

    MarshallingPayloadMethodProcessor processor = new MarshallingPayloadMethodProcessor(marshaller); 
    beanFactory.registerSingleton(beanName, processor); 
    } 

paar Einschränkungen auf diesem:

  • Wenn über ein Glas bereitstellen, dann Classpath Verzeichnisse nicht existieren, so wird eine alternative Art und Weise müssen die Paketnamen zu erhalten.
  • registerSingleton scheint einige Anwendungskontexte zu brechen - wodurch nicht verwandte Beans nicht mehr gefunden werden. Ich habe keine Ahnung, warum das so ist.
Verwandte Themen