简体   繁体   English

“端点没有适配器”异常 - apache-camel with spring-boot & spring-ws

[英]'No adapter for endpoint' exception - apache-camel with spring-boot & spring-ws

JVM 1.8.0_45 JVM 1.8.0_45
apache-camel 2.15.2阿帕奇骆驼2.15.2
spring-ws 2.2.1弹簧-WS 2.2.1
spring-boot 1.2.4弹簧靴1.2.4

I am trying to use apache-camel (2.15.2) within a spring-boot application to handle incoming web service calls.我正在尝试在 spring-boot 应用程序中使用 apache-camel (2.15.2) 来处理传入的 Web 服务调用。

I created an initial working spring boot project (no camel) following the guidelines here http://spring.io/guides/gs/producing-web-service/我按照http://spring.io/guides/gs/production-web-service/的指南创建了一个初始工作 spring boot 项目(没有骆驼)

I then attempted to integrate the Camel: Spring Web Services component as a Consumer to handle incoming web service requests following guidelines in the 'Exposing Web Services' section here http://camel.apache.org/spring-web-services.html然后,我尝试将 Camel: Spring Web Services 组件集成为消费者,以按照此处http://camel.apache.org/spring-web-services.html的“公开 Web 服务”部分中的指南处理传入的 Web 服务请求

WebServiceConfig.java网络服务配置文件

import org.apache.camel.component.spring.ws.bean.CamelEndpointMapping;

@EnableWs
@Configuration
public class WebServiceConfig extends WsConfigurerAdapter {

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

    // default wsdl stuff here...

    // exposing the endpoint mapping bean here rather than in spring-ws-servlet.xml (seems to work)
    @Bean  public CamelEndpointMapping  endpointMapping() {
        return new CamelEndpointMapping();
    }
}

ClaimRouter.java声明路由器.java

import org.apache.camel.LoggingLevel;
import org.apache.camel.builder.RouteBuilder;
import org.apache.camel.model.dataformat.JaxbDataFormat;
import org.springframework.stereotype.Component;

@Component
public class ClaimRouter extends RouteBuilder {

    @Override
    public void configure() throws Exception {

        JaxbDataFormat jaxb = new JaxbDataFormat(false);
        jaxb.setContextPath("uk.co.example.claim.ws.v2"); 

        // comment @PayloadRoot annotation in ClaimEndpointV2.java to enable requests to be mapped to this camel route
        from("spring-ws:rootqname:{http://example.co.uk/claim/ws/v2}getClaimRequest?endpointMapping=#endpointMapping")
        .to("log:uk.co.example.claim.ws.v2?level=INFO")
        .unmarshal(jaxb)
        .process(new ClaimProcessor())
        .marshal(jaxb);
    }
}

According to the log (below) incoming requests are successfully mapped to my Camel Consumer, but then it fails with 'No adapter for endpoint'根据日志(下面)传入的请求已成功映射到我的 Camel 消费者,但随后失败并显示“端点没有适配器”

[2015-06-24 13:22:03.981] boot - 6892 DEBUG [http-nio-8090-exec-6] --- WsdlDefinitionHandlerAdapter: Transforming [/ws] to [http://localhost:8090/ws]
[2015-06-24 13:22:03.983] boot - 6892 DEBUG [http-nio-8090-exec-6] --- MessageDispatcherServlet: Successfully completed request
[2015-06-24 13:22:13.544] boot - 6892 DEBUG [http-nio-8090-exec-7] --- WebServiceMessageReceiverHandlerAdapter: Accepting incoming [org.springframework.ws.transport.http.HttpServletConnection@70863933] at [http://localhost:8090/ws]
[2015-06-24 13:22:13.547] boot - 6892 DEBUG [http-nio-8090-exec-7] --- received: Received request [SaajSoapMessage {http://example.co.uk/claim/ws/v2}getClaimRequest]
[2015-06-24 13:22:13.547] boot - 6892 DEBUG [http-nio-8090-exec-7] --- PayloadRootAnnotationMethodEndpointMapping: Looking up endpoint for [{http://example.co.uk/claim/ws/v2}getClaimRequest]
[2015-06-24 13:22:13.547] boot - 6892 DEBUG [http-nio-8090-exec-7] --- SoapMessageDispatcher: Endpoint mapping [org.springframework.ws.server.endpoint.mapping.PayloadRootAnnotationMethodEndpointMapping@5fdbde50] has no mapping for request
[2015-06-24 13:22:13.547] boot - 6892 DEBUG [http-nio-8090-exec-7] --- SoapActionAnnotationMethodEndpointMapping: Looking up endpoint for []
[2015-06-24 13:22:13.547] boot - 6892 DEBUG [http-nio-8090-exec-7] --- SoapMessageDispatcher: Endpoint mapping [org.springframework.ws.soap.server.endpoint.mapping.SoapActionAnnotationMethodEndpointMapping@50bf4dcb] has no mapping for request
[2015-06-24 13:22:13.547] boot - 6892 DEBUG [http-nio-8090-exec-7] --- SoapMessageDispatcher: Endpoint mapping [org.springframework.ws.soap.addressing.server.AnnotationActionEndpointMapping@8b5028a] has no mapping for request
[2015-06-24 13:22:13.548] boot - 6892 DEBUG [http-nio-8090-exec-7] --- SoapMessageDispatcher: Endpoint mapping [org.apache.camel.component.spring.ws.bean.CamelEndpointMapping@7a9ff5b1] maps request to endpoint [Consumer[spring-ws://rootqname:(http://example.co.uk/claim/ws/v2)getClaimRequest?endpointMapping=%23endpointMapping]]
[2015-06-24 13:22:13.548] boot - 6892 DEBUG [http-nio-8090-exec-7] --- SoapMessageDispatcher: Testing endpoint adapter [org.springframework.ws.server.endpoint.adapter.DefaultMethodEndpointAdapter@5a1e093a]
[2015-06-24 13:22:13.549] boot - 6892 DEBUG [http-nio-8090-exec-7] --- SoapFaultAnnotationExceptionResolver: Resolving exception from endpoint [Consumer[spring-ws://rootqname:(http://example.co.uk/claim/ws/v2)getClaimRequest?endpointMapping=%23endpointMapping]]: java.lang.IllegalStateException: No adapter for endpoint [Consumer[spring-ws://rootqname:(http://example.co.uk/claim/ws/v2)getClaimRequest?endpointMapping=%23endpointMapping]]: Is your endpoint annotated with @Endpoint, or does it implement a supported interface like MessageHandler or PayloadEndpoint?
[2015-06-24 13:22:13.549] boot - 6892 DEBUG [http-nio-8090-exec-7] --- SimpleSoapExceptionResolver: Resolving exception from endpoint [Consumer[spring-ws://rootqname:(http://example.co.uk/claim/ws/v2)getClaimRequest?endpointMapping=%23endpointMapping]]: java.lang.IllegalStateException: No adapter for endpoint [Consumer[spring-ws://rootqname:(http://example.co.uk/claim/ws/v2)getClaimRequest?endpointMapping=%23endpointMapping]]: Is your endpoint annotated with @Endpoint, or does it implement a supported interface like MessageHandler or PayloadEndpoint?
[2015-06-24 13:22:13.549] boot - 6892 DEBUG [http-nio-8090-exec-7] --- SoapMessageDispatcher: Endpoint invocation resulted in exception - responding with Fault
java.lang.IllegalStateException: No adapter for endpoint [Consumer[spring-ws://rootqname:(http://example.co.uk/claim/ws/v2)getClaimRequest?endpointMapping=%23endpointMapping]]: Is your endpoint annotated with @Endpoint, or does it implement a supported interface like MessageHandler or PayloadEndpoint?
        at org.springframework.ws.server.MessageDispatcher.getEndpointAdapter(MessageDispatcher.java:302)
        at org.springframework.ws.server.MessageDispatcher.dispatch(MessageDispatcher.java:235)
        at org.springframework.ws.server.MessageDispatcher.reessageDispatcher.java:176)
        at org.springframework.ws.transport.support.WebServiceMessageReceiverObjectSupport.handleConnection(WebServiceMessageReceiverObjectSupport.java:89)
        at org.springframework.ws.transport.http.WebServiceMessageReceiverHandlerAdapter.handle(WebServiceMessageReceiverHandlerAdapter.java:61)
        at org.springframework.ws.transport.http.MessageDispatcherServlet.doService(MessageDispatcherServlet.java:293)
        at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:966)
        at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:868)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:648)
        at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:842)
        at javax.servlet.http.HttpServlet.service(HttpServlet.java:729)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:291)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
        at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:85)
        at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
        at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:239)
        at org.apache.catali.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
        at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:219)
        at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:106)
        at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
        at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:142)
        at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79)
        at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:88)
        at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:518)
        at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1091)
        at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:668)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1521)
        at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.run(NioEndpoint.java:1478)
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
        at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
        at java.lang.Thread.run(Thread.java:745)
[2015-06-24 13:22:13.554] boot - 6892 DEBUG [http-nio-8090-exec-7] --- sent: Sent response [SaajSoapMessage {http://schemas.xmlsoap.org/soap/envelope/}Fault] for request [SaajSoapMessage {http://example.co.uk/claim/ws/v2}getClaimRequest]
[2015-06-24 13:22:13.556] boot - 6892 DEBUG [http-nio-8090-exec-7] --- MessageDispatcherServlet: Successfully completed request

My gradle dependencies are as follows:我的gradle依赖如下:

dependencies {
    compile("org.springframework.boot:spring-boot-starter-ws") {
        exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
    }
    compile("org.springframework.boot:spring-boot-starter") {
        exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
    }
    compile("org.springframework.boot:spring-boot-starter-log4j")
    compile("org.springframework:spring-web")
    compile("com.fasterxml.jackson.core:jackson-databind")
    compile("org.apache.camel:camel-core:2.15.2")
    compile("org.apache.camel:camel-spring-boot:2.15.2")
    compile("org.apache.camel:camel-spring-ws:2.15.2")
    compile("org.apache.camel:camel-jaxb:2.15.2")
    testCompile("org.springframework.boot:spring-boot-starter-test")
    compile 'org.slf4j:slf4j-log4j12:1.7.12'
    compile("wsdl4j:wsdl4j:1.6.1")
    jaxb("com.sun.xml.bind:jaxb-xjc:2.2.4-1")
    compile sourceSets.generated.output
}

I've researched a large number of No adapter for endpoint problems and most of them seem to be caused by the return type of the endpoint.我研究了大量的无适配器端点问题,其中大多数似乎是由端点的返回类型引起的。 However, I'm just creating a camel route, so presumably the camel-spring-ws integration should be providing the actual endpoint.但是,我只是在创建一条骆驼路线,所以大概是骆驼弹簧 ws集成应该提供实际的端点。

Am I missing a key piece of configuration/annotation or is there a more fundamental problem (some version incompatibility, perhaps)?我是否缺少配置/注释的关键部分,或者是否存在更基本的问题(可能是某些版本不兼容)? Any help or insights much appreciated.非常感谢任何帮助或见解。

When spring boot is used, it registers just DefaultMethodEndpointAdapter that configures annotation driven Spring WS programming model.当使用 spring boot 时,它只注册DefaultMethodEndpointAdapter来配置注解驱动的 Spring WS 编程模型。 This makes it possible to use the various annotations like @Endpoint , @Payload auto detected.这使得使用各种注释成为可能,例如@Endpoint@Payload自动检测。

As in our case, spring-ws endpoint has to hand over ws requests to camel endpoint, DefaultMethodEndpointAdapter won't do that job for us.在我们的例子中,spring-ws 端点必须将 ws 请求移交给骆驼端点, DefaultMethodEndpointAdapter不会为我们完成这项工作。

Below is the part of the code in the spring framework that does the end point adapters registration,下面是 spring 框架中执行端点适配器注册的部分代码,

private void initEndpointAdapters(ApplicationContext applicationContext) throws BeansException {

    if (endpointAdapters == null) {
        Map<String, EndpointAdapter> matchingBeans = BeanFactoryUtils
                .beansOfTypeIncludingAncestors(applicationContext, EndpointAdapter.class, true, false);


        if (!matchingBeans.isEmpty()) {
            endpointAdapters = new ArrayList<EndpointAdapter>(matchingBeans.values());
            Collections.sort(endpointAdapters, new OrderComparator());          
        }

        else {
            endpointAdapters =
                    defaultStrategiesHelper.getDefaultStrategies(EndpointAdapter.class, applicationContext);
            if (logger.isDebugEnabled()) {
                logger.debug("No EndpointAdapters found, using defaults");
            }
        }
    }
} 

When we use spring-boot, DefaultMethodEndpointAdapter gets registered and hence the first 'if block' runs and hence it doesn't register other adapters like MessageEndpointAdapter , PayloadEndpointAdapter etc.当我们使用 spring-boot 时, DefaultMethodEndpointAdapter被注册,因此第一个“if 块”运行,因此它不会注册其他适配器,如MessageEndpointAdapterPayloadEndpointAdapter等。

What we need in this case is, other than DefaultMethodEndpointAdapter , have to register MessageEndpointAdapter as well to offload spring-ws to camel endpoints.在这种情况下,我们需要的是,除了DefaultMethodEndpointAdapter ,还必须注册MessageEndpointAdapter以将 spring-ws 卸载到骆驼端点。

So in WebServiceConfig class, add the below code,所以在WebServiceConfig类中,添加以下代码,

@Bean
    public EndpointAdapter messageEndpointAdapter() {
        return new MessageEndpointAdapter();
    }

then the handover magic happens.然后切换魔法发生了。

MessageEndpointAdapter is required for spring-ws and camel handover. spring-ws和camel切换需要MessageEndpointAdapter

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM