Search code examples
javaspringspring-bootweb-servicessoap

Multiple SOAP endpoints with one namespace & localpart


I created a SOAP web service server with SpringBoot and I was able to successfully create one endpoint. However, I cannot create multiple endpoints and access them with different URLs. I want to handle the process by URL to access.

The SOAP message received by each endpoint has the same schema. (Namespace and localpart are the same !!!) And I don't want to make the WSDL public.

For example.

userA sends the following SOAP message to the following URL: http://soap.example.com/ws/userA

<S:Envelope>
    <SOAP-ENV:Header>
    </SOAP-ENV:Header>
    <S:Body>
        <testsoap:post
            xmlns:testsoap="http://soap.example.com/">
            <testsoap:message>
                I am UserA
            </testsoap:message>
        </testsoap:post>
    </S:Body>
</S:Envelope>

userB sends the following SOAP message to the URL: http://soap.example.com/ws/userB

<S:Envelope>
    <SOAP-ENV:Header>
    </SOAP-ENV:Header>
    <S:Body>
        <testsoap:post
            xmlns:testsoap="http://soap.example.com/">
            <testsoap:message>
                I am UserB
            </testsoap:message>
        </testsoap:post>
    </S:Body>
</S:Envelope>

The source code is as follows:

@EnableWs
@Configuration
public class WebServiceConfig extends WsConfigurerAdapter {
    
    @Autowired
    CustomConfig customConfig;

    @Bean
    public ServletRegistrationBean<MessageDispatcherServlet> messageDispatherServlet(ApplicationContext applicationContext) {
        MessageDispatcherServlet servlet = new MessageDispatcherServlet();
        servlet.setApplicationContext(applicationContext);
        servlet.setTransformWsdlLocations(true);
        return new ServletRegistrationBean<MessageDispatcherServlet>(servlet, "/ws/*");
    }
}

I want to access at http://soap.example.com/ws/userA

@Endpoint
public class SoapRequestEndpoint {
    private static final String NAMESPACE_URI = "http://soap.example.com/";

    @PayloadRoot(namespace = NAMESPACE_URI, localPart = "post")
    @ResponsePayload
    public JAXBElement<PostResponse> postForA(MessageContext messageContext) {
        // do something for userA
    }
}

I want to access at http://soap.example.com/ws/userB

@Endpoint
public class SoapRequestEndpoint {
    private static final String NAMESPACE_URI = "http://soap.example.com/";

    @PayloadRoot(namespace = NAMESPACE_URI, localPart = "post")
    @ResponsePayload
    public JAXBElement<PostResponse> postForB(MessageContext messageContext) {
        // do something for userB
    }
}

Solution

  • Try to create an additional Wsdl11Definition method in the WebServiceConfig class and annotate the method with @Bean(name = "UserB").

    You have only shown a snippet from your WebServiceConfig class, I am assuming that this is absent from the class.

    Your class should look similar to this:

    @EnableWs
    @Configuration
    public class WebServiceConfig extends WsConfigurerAdapter {
    
        @Autowired
        CustomConfig customConfig;
    
        @Bean
        public ServletRegistrationBean<MessageDispatcherServlet> messageDispatherServlet(ApplicationContext applicationContext) {
            MessageDispatcherServlet servlet = new MessageDispatcherServlet();
            servlet.setApplicationContext(applicationContext);
            servlet.setTransformWsdlLocations(true);
            return new ServletRegistrationBean<MessageDispatcherServlet>(servlet, "/ws/*");
        }
    }
    
    @Bean(name = "userA")
        public DefaultWsdl11Definition defaultWsdl11Definition(XsdSchema [randomMethodSchema]) {
            DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
            wsdl11Definition.setPortTypeName("userAPort");
            wsdl11Definition.setLocationUri("/ws");
            wsdl11Definition.setTargetNamespace("http://soap.example.com/");
            wsdl11Definition.setSchema([randomMethodSchema]);
            return wsdl11Definition;
        }
    
    @Bean(name = "userB")
        public DefaultWsdl11Definition defaultWsdl11Definition2(XsdSchema [randomMethodSchema]) {
            DefaultWsdl11Definition wsdl11Definition = new DefaultWsdl11Definition();
            wsdl11Definition.setPortTypeName("userBPort");
            wsdl11Definition.setLocationUri("/ws");
            wsdl11Definition.setTargetNamespace("http://soap.example.com/");
            wsdl11Definition.setSchema([randomMethodSchema]);
            return wsdl11Definition;
        }
    
        @Bean
        public XsdSchema [randomMethodSchema]() {
            return new SimpleXsdSchema(new ClassPathResource([schema name].xsd));
        }
    }
    

    HTH