具有Spring Integration的SOAP代理

iLi*_*ast 2 spring soap web-services spring-integration spring-boot

我试图将精力集中在Spring集成上,并且最好不要使用基于XML的配置。

我想做的是以下几点:

  1. Accept a SOAP request on a certain endpoint
  2. Forward this request to a downstream SOAP service, without any modification (for now I just want the basics to work)
  3. Return the result to the client

This seems like it should be pretty simple, but I don't have the faintest idea of where to start. Is this even possible with SI? As I understand it, and please correct me if I'm wrong, SI is mainly used for async data flows.

I did check out the integration sample repository, which includes example inbound WS requests, but these are all configured in XML, which, as I said, I'd preferably like to stay far away from.

Any pointers would be much appreciated; I've been reading through documentation for the past two days and I'm none the wiser!

abe*_*abe 5

这是使用SimpleWebServiceInboundGateway的示例。在此示例中,我们还将“ ExtractPayload”设置为false,以便它发送RAW soap消息。但与上述观点一致,HTTPInboundRequest可能更适合您的用例。我也没有发现很多将DSL用于SoapInboundGateway的示例,因此希望共享并希望它对其他人有所帮助。

@Configuration
@EnableIntegration
public class SoapGatewayConfiguration {

    /**
     * URL mappings used by WS endpoints
     */
    public static final String[] WS_URL_MAPPINGS = {"/services/*", "*.wsdl", "*.xsd"};
    public static final String GATEWAY_INBOUND_CHANNEL_NAME  = "wsGatewayInboundChannel";
    public static final String GATEWAY_OUTBOUND_CHANNEL_NAME = "wsGatewayOutboundChannel";


    /**
     * Register the servlet mapper, note that it uses MessageDispatcher
     */
    @Bean
    public ServletRegistrationBean messageDispatcherServlet(ApplicationContext applicationContext) {
        MessageDispatcherServlet servlet = new MessageDispatcherServlet();
        servlet.setApplicationContext(applicationContext);
        servlet.setTransformWsdlLocations(true);
        servlet.setTransformSchemaLocations(true);
        servlet.setPublishEvents(true);
        ServletRegistrationBean servletDef = new ServletRegistrationBean(servlet, WS_URL_MAPPINGS);
        servletDef.setLoadOnStartup(1);
        return servletDef;
    }

    /**
     * Create a new Direct channels to handle the messages
     */
    @Bean
    public MessageChannel wsGatewayInboundChannel() {
        return MessageChannels.direct(GATEWAY_INBOUND_CHANNEL_NAME).get();
    }
    @Bean
    public MessageChannel wsGatewayOutboundChannel() {
        return MessageChannels.direct(GATEWAY_OUTBOUND_CHANNEL_NAME).get();
    }

    /**
     * Startup the WebServiceInboundGateway Endpoint, this will handle the incoming SOAP requests
     *  and place them onto the request channel
     */
    @Bean
    public SimpleWebServiceInboundGateway webServiceInboundGateway(
            @Value("${spring.ws.request.timeout:1000}") long requestTimeout,
            @Value("${spring.ws.reply.timeout:1000}") long replyTimeout,
            @Value("${spring.ws.should.track:true}") boolean shouldTrack
    ) {
        SimpleWebServiceInboundGateway wsg = new SimpleWebServiceInboundGateway();
        wsg.setRequestChannel(wsGatewayInboundChannel());
        wsg.setReplyChannel(wsGatewayOutboundChannel());
        wsg.setExtractPayload(false);  // Send the full RAW SOAPMessage and not just payload
        wsg.setLoggingEnabled(true);
        wsg.setShouldTrack(shouldTrack);
        wsg.setReplyTimeout(replyTimeout); // Do not believe this prop supported currently
        wsg.setRequestTimeout(requestTimeout); // Do not believe this prop is supported currently
        wsg.setCountsEnabled(true);
        return wsg;
    }

    /**
     * You must enable debug logging on org.springframework.ws.server.endpoint.interceptor.PayloadLoggingInterceptor
     *  to see the logs from this interceptor
     */
    @Bean
    public EndpointInterceptor soapMessageLoggingInterceptor() {
        SoapEnvelopeLoggingInterceptor li = new SoapEnvelopeLoggingInterceptor();
        li.setLogRequest(true);
        li.setLogResponse(true);
        li.setLogFault(true);
        return li;
    }


    /**
     * Validate the incoming web service against the schema
     */
    @Bean
    public EndpointInterceptor payloadValidatingInterceptor(XsdSchema xsdSchema
            , @Value("${spring.ws.soap.validate.request:true}") boolean soapValidateRequest
            , @Value("${spring.ws.soap.validate.reply:true}") boolean soapValidateResponse
            , @Value("${spring.ws.soap.validate.addErrorDetail:true}") boolean soapAddValidationErrorDetail

    ) {
        PayloadValidatingInterceptor interceptor = new PayloadValidatingInterceptor();
        interceptor.setXsdSchema(xsdSchema);
        interceptor.setValidateRequest(soapValidateRequest);
        interceptor.setValidateResponse(soapValidateResponse);
        interceptor.setAddValidationErrorDetail(soapAddValidationErrorDetail);
        return interceptor;
    }

    /**
     * Map the allowable service Uri's.
     */
    @Bean
    public EndpointMapping uriEndpointMapping(
             PayloadValidatingInterceptor payloadValidatingInterceptor
            , SimpleWebServiceInboundGateway webServiceInboundGateway
            , SoapEnvelopeLoggingInterceptor loggingInterceptor) {
        UriEndpointMapping mapping = new UriEndpointMapping();
        mapping.setUsePath(true);
        mapping.setDefaultEndpoint(webServiceInboundGateway());
        mapping.setInterceptors(new EndpointInterceptor[]{loggingInterceptor, payloadValidatingInterceptor});
        return mapping;
    }

    /**
     * Expose the wsdl at http://localhost:8080/services/myService.wsdl
     **/    
    @Bean
    public Wsdl11Definition defaultWsdl11Definition() {
        SimpleWsdl11Definition wsdl11Definition = new SimpleWsdl11Definition();
        wsdl11Definition.setWsdl(new ClassPathResource("META-INF/myService.wsdl"));
        return wsdl11Definition;
    }

    /**
     * Expose the xsd at http://localhost:8080/services/mySchema.xsd
     **/
    @Bean
    public XsdSchema mySchema() {
        return new SimpleXsdSchema(new ClassPathResource("META-INF/mySchema.xsd"));
    }    

    @Bean
    public IntegrationFlow itemLookupFlow() {
        return IntegrationFlows.from("wsGatewayInboundChannel")
                .log(LoggingHandler.Level.INFO)
                .handle(myBeanName, "execute")
                .log(LoggingHandler.Level.TRACE, "afterExecute")
                .get();
    }

}
Run Code Online (Sandbox Code Playgroud)