代码之家  ›  专栏  ›  技术社区  ›  andersfylling

Spring配置两个@端点,每个端点都有一个唯一的wsdl文件

  •  5
  • andersfylling  · 技术社区  · 7 年前

    我已经能够使用wsdl文件获得一个@端点:

    @EnableWs
    @Configuration
    public class EventServerConfiguration extends WsConfigurerAdapter {
        @Bean
        public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
            MessageDispatcherServlet servlet = new MessageDispatcherServlet();
            servlet.setApplicationContext(applicationContext);
            servlet.setTransformWsdlLocations(true);
            return new ServletRegistrationBean(servlet, "/event");
        }
    
    
        @Bean(name = "wsdl-event")
        public Wsdl11Definition defaultWsdl11Definition() {
            SimpleWsdl11Definition wsdl11Definition = new SimpleWsdl11Definition();
            wsdl11Definition.setWsdl(new ClassPathResource("/wsdl/event.wsdl"));
            return wsdl11Definition;
        }
    
        @Bean
        AnnotationActionEndpointMapping endpointMapping() {
            AnnotationActionEndpointMapping mapping = new AnnotationActionEndpointMapping();
            return mapping;
        }
    }
    

    但对于我的用例,我需要处理两个wsdl文件。最初,我设置了一个RestController,并从xml POST请求中解压了正文,但现在我想尝试纯spring方式。

    我假设需要创建两个MessageDispatcherServlet,每个wsdl定义一个,但我不知道如何正确映射或注册端点。

    有什么想法吗?

    我创建了duplicate(使用不同的wsdl和bean名称) WSDLdefinition 豆子,和 messageDispatcherServlet 通过 ServletRegistrationBean 给了我错误 Servlet messageDispatcherServlet was not registered (possibly already registered?) 虽然我的端点似乎出现了,但spring会在对所述端点的任何请求上返回404。

    Spring ws版本:3

    1 回复  |  直到 7 年前
        1
  •  5
  •   andersfylling    7 年前

    我的假设是,每个Spring@Enpoint类需要不同的路径。我现在意识到我只需要注册一个 MessageDispatcherServlet 并定义处理传入请求所需的wsdl文件。

    因为我需要两个不同的wsdl文件,所以我可以通过创建一个来支持这两个文件 ServletRegistrationBean 持有 MessageDispatcherServlet Wsdl11Definition bean(每个wsdl文件一个),并且在我的@Endpoint类中,我将名称空间和localPart设置为 @PayloadRoot 注释。

    配置类

    // Configuration class
    @EnableWs
    @Configuration
    public class SpringConfiguration 
    {
        @Bean
        public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) 
        {
            MessageDispatcherServlet servlet = new MessageDispatcherServlet();
            servlet.setApplicationContext(applicationContext);
            servlet.setTransformWsdlLocations(true);
    
            return new ServletRegistrationBean(servlet, "/soap");
        }
    
        @Bean
        AnnotationActionEndpointMapping annotationActionEndpointMapping() 
        {
            AnnotationActionEndpointMapping mapping = new AnnotationActionEndpointMapping();
            // add any interceptors here for features like logging
            return mapping;
        }
    
        // wsdl file A
        @Bean(name="wsdl-definition-A")
        public Wsdl11Definition wsdl11DefinitionA()
        {
            SimpleWsdl11Definition def = new SimpleWsdl11Definition();
            wsdl11Definition.setWsdl(new ClassPathResource("wsdl/A.wsdl"));
    
            return wsdl11Definition;
        }
    
        // wsdl file B
        @Bean(name="wsdl-definition-B")
        public Wsdl11Definition wsdl11DefinitionA()
        {
            SimpleWsdl11Definition def = new SimpleWsdl11Definition();
            wsdl11Definition.setWsdl(new ClassPathResource("wsdl/B.wsdl"));
    
            return wsdl11Definition;
        }
    }
    

    如果需要到端点的不同路径,而不是一条。我 假定 您需要调整 ServletRegistrationBean 上述定义。现在所有内容都映射到 "/soap"

    以下是端点:

    @Endpoint
    public class AServer
    {
        private final static String NAMESPACE_URI = "http://some.namespace/v3/idk/am/i/even/real";
        private final static String LOCALPART = "XMLElementName";
        private final SomeMarshaller marshaller;
    
        @Autowired
        public EventServer(EventReceiveMarshaller marshaller) 
        {
            // I use a marshaller class to simplify my life
            this.marshaller = marshaller; 
        }
    
        @Override
        @ResponsePayload
        @PayloadRoot(namespace = NAMESPACE_URI, localPart = LOCALPART)
        public JAXBElement<SomeResponseMessageType> triggerResponse(@RequestPayload JAXBElement<SomeRequestMessageType> msg) {
    
            // do something with the `msg` request
    
            // Send a OK response
            return this.marshaller.createReply(msg);
        }
    }
    

    然后 BServer AServer 除了 NAMESPACE_URI LOCALPART 因为它们依赖于各自的wsdl文件。