2016-09-06 9 views
0

각 아웃 바운드 메시지에 대해 Salesforce는 완전한 자체 포함 WSDL을 제공합니다.동일한 Spring 서비스에서 다중 SFDC 아웃 바운드 메시지 수신기를 구현하는 방법은 무엇입니까?

하나의 스프링 서비스를 구현하는 것은 간단합니다. jaxws-maven-plugin을 사용하여 클래스를 생성하고 @Endpoint, @PayloadRoot 등을 사용하여 엔드 포인트를 바인딩합니다.

그러나 여러 아웃 바운드 메시지는 서로 다른 구조 및 유형 계층 구조에 대해 동일한 QN (예 : http://soap.sforce.com/2005/09/outbound:notifications 또는 urn:sobject.enterprise.soap.sforce.com:sObject)을 공유합니다.

나는 how to map the same XML names to different handlers based on URL path을 알고 있습니다. 생성 된 코드에서 Jaxb2Marshaller을 초기화 할 때 그러나

<?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> 

, 그것은 여전히 ​​XML 충돌을 처리 할 수 ​​없습니다 :

은 내가 바인딩 파일로 생성 된 클래스에 대해 별도의 패키지를 사용하는 방법을 알고

[WARN] [main] 09:40:45.687 AnnotationConfigEmbeddedWebApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: 
    Error creating bean with name 'marshaller' defined in class path resource [WebServiceConfig.class]: 
    Invocation of init method failed; nested exception is org.springframework.oxm.UncategorizedMappingException: 
    Unknown JAXB exception; nested exception is com.sun.xml.internal.bind.v2.runtime.IllegalAnnotationsException: 6 counts of IllegalAnnotationExceptions 
    Two classes have the same XML type name "{urn:sobject.enterprise.soap.sforce.com}sObject". Use @XmlType.name and @XmlType.namespace to assign different names to them. 
    ... 

새 파일을 삭제하는 것 외에 SDFC 생성 WSDL이 변경 될 때 수동 단계를 추가하고 싶지 않습니다.

소스 WSDL을 변경하지 않고 package-info.java의 네임 스페이스를 변경하는 방법이 있습니까?

DefaultMethodEndpointAdapter에 모두 추가 할 수있는 각 패키지마다 별도의 마샬 러를 쉽게 만들 수 있나요? 예 : 각각 별도의 @Bean 메소드가 필요하지 않습니까?

이러한 모든 아웃 바운드 메시지 수신자를 구현할 수있는 또 다른 방법이 있습니까?

답변

0

네임 스페이스를 변경하는 방법이 있습니까?

액티비티 메시지의 네임 스페이스와 일치하지 않으므로 언 마샬 할 수 없습니다.

각 패키지마다 별도의 마샬 러를 쉽게 만들 수 있나요?

음, 여기가 입니다. 이에 대한주의의

@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); 
    } 

커플 :

  • 항아리를 통해 배포 할 경우, 클래스 경로 디렉토리가 존재하지 않기 때문에 패키지 이름을 얻기 위해 다른 방법이 필요합니다.
  • registerSingleton은 관련없는 빈을 더 이상 찾을 수 없도록 일부 응용 프로그램 컨텍스트를 손상시키는 것으로 보입니다. 나는 이것이 왜 있는지 전혀 모른다.