【问题标题】:How to implement webservice version gateway with Apache Camel, CXF and Spring Boot如何使用 Apache Camel、CXF 和 Spring Boot 实现 webservice 版本网关
【发布时间】:2016-01-27 16:57:39
【问题描述】:

我目前正在做一个项目,我使用 Apache Camel、CXF 来实现我的 WebService。最重要的是,我使用 Spring Boot(嵌入了 tomcat)。

我为每个 Web 服务版本开发了不同的 CXF 端点,可以通过以下方式访问它们 http://myserver.com/service/V1http://myserver.com/service/V2。这一切都很好,除非我需要让这些服务在一个 url http://myserver.com/service/CommonVersion 下工作并基于 xpath 将其路由到特定版本。

我真的不知道如何配置,然后将 Web 服务请求从公共入口点发送到特定于版本的入口点。

我想为我的应用程序提供一些设置: cxf-context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:camel="http://camel.apache.org/schema/spring" xmlns:cxf="http://camel.apache.org/schema/cxf" xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring  http://camel.apache.org/schema/spring/camel-spring.xsd  http://camel.apache.org/schema/cxf http://camel.apache.org/schema/cxf/camel-cxf.xsd">

  <cxf:cxfEndpoint id="serviceV1"
                 address="/service/V1" serviceName="s:Service" serviceClass="com.myservice.v1.service" xmlns:s="http://com.myservice/ServiceV1">
   <cxf:properties>
      <entry key="allowStreaming" value="false" />
   </cxf:properties>
  </cxf:cxfEndpoint>

  <cxf:cxfEndpoint id="serviceV2" address="/service/V2" serviceName="s:Service" serviceClass="com.myservice.v2.service" xmlns:s="http://com.myservice/ServiceV2">
   <cxf:properties>
      <entry key="allowStreaming" value="false" />
   </cxf:properties>
  </cxf:cxfEndpoint>
</beans>

为我的 cxf 端点定义的示例路由

@Component
public class ServiceV1 extends SpringRouteBuilder {
  public void configure() throws Exception {
    from("cxf:bean:serviceV1").to("mock:processFurther")
  }

}

我的应用配置如下:

@SpringBootApplication
@ImportResource({ "/cxf-context.xml" })
public class Application extends SpringBootServletInitializer {
  public static void main(String[] args) {
    SpringApplication.run(Application.class, args);
  }

  @Override
  protected SpringApplicationBuilder configure(
        SpringApplicationBuilder application) {
    return super.configure(application).sources(Application.class);
  }

  @Bean
  public ServletRegistrationBean servletRegistrationBean() {
    CXFServlet servlet = new CXFServlet();
    return new ServletRegistrationBean(servlet, "/*");
  }
}

【问题讨论】:

  • 我发现了一篇关于类似问题的博客文章:waterback.github.io/blog/2012/03/02/… 但是提出的解决方案依赖于码头,它打开了两个端口。问题描述很相似
  • 我相信 serviceCommon 端点不必是 cxf。它可能是一个 netty-http 端点......

标签: web-services spring-boot apache-camel cxf


【解决方案1】:

您肯定知道,使用 CXF 和 Camel,服务的实现是由路由本身完成的。

我会将您所谓的“ServiceV1”(“extends SpringRouteBuilder”)重命名为“Routes”(因为所有路由都在其中,而不仅仅是一个服务),并像这样实现 - 只是一个例子让事情变得现实:

@Component
public class MyRoutes extends SpringRouteBuilder {
    public void configure() throws Exception {
        from("cxf:bean:serviceV1")
                .to("direct:v1");

        from("cxf:bean:serviceV2")
                .to("direct:v2");

        from("cxf:bean:serviceCommon")
                .choice()
                    .when(header("version").isEqualTo("v1"))
                        .to("direct:v1")
                    .otherwise()
                        .to("direct:v2")
                .end();

        from("direct:v1")
                .beanRef("paymentservicev1", "buy");

        from("direct:v1")
                .beanRef("paymentservicev2", "buy");

    }
}

在这里,我没有打开 xpath,而是打开了标头值——你明白了。那是你想要的吗?

【讨论】:

  • 理论上可行,但是让我们考虑以下情况:V1 和 V2 不兼容,并且您将 CXF 请求映射到一个来自包 v1 的对象,另一个来自包 v2。您还希望启用 XML 验证(至少在 QA 中)。您应该在 serviceCommon cxfEndpoint 上使用什么数据格式类型?尽管您正在通过 serviceCommon,如何仍然验证 V1 和 V2 的请求?
猜你喜欢
  • 1970-01-01
  • 2019-03-01
  • 1970-01-01
  • 2018-11-19
  • 1970-01-01
  • 1970-01-01
  • 2018-01-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多