在 CXF 中使用 javax.ws.rs.client.ClientBuilder 创建客户端,任何路由都可以使用本地传输?

Using javax.ws.rs.client.ClientBuilder in CXF to create Client, any route to be able to use local transport?

我在使用 CXF 发行版中的标准“javax.ws.rs.client.ClientBuilder”class 的代码库上配置和创建“javax.ws.rs.client.Client”。

这很好用。

我现在正在尝试编写使用 JAXRSServerFactoryBean 的测试来管理使用由内联 class 定义的控制器的假服务器。我可以在测试和客户端配置中将我的 host:port 设置为 localhost:something,这足以让我测试我们的 MessageBodyReaders 和 Http 异常处理。

但是,我认为这不会是 "scalable",因为每个假服务器都必须 运行 在 "dedicated" 端口上(而 运行 测试, 至少)。我可以尝试使用不常见的端口,让不同的测试使用不同的端口,或者使用随机数,但这都有点冒险。我真的不希望 CI 构建失败,因为并行测试 运行ning 最终使用相同的端口。

我读到了 CXF(而非 JAX-RS)中使用 "local transport" (https://cwiki.apache.org/confluence/display/CXF20DOC/JAXRS+Testing) 的能力。看来这可能会解决我的问题。我需要验证这一点,但有可能 运行 同时使用本地传输的两个测试不会发生冲突。

但是,我什至还不能让它工作,因为我们的客户端代码使用的是 "standard" JAX-RS 客户端 class,而不是 CXF 客户端。它们似乎不同且不兼容。

在我创建客户端时,我尝试这样做(只是为了看看它是否可以工作):

WebClient.getConfig(client).getRequestContext().put(LocalConduit.DIRECT_DISPATCH, Boolean.TRUE);

不幸的是,“org.apache.cxf.jaxrs.client.WebClient.getConfig(Object)”中的 "Not a valid Client" 失败了,因为它需要是“org.apache.cxf.jaxrs.client.Client”的实例,而不是 javax.ws.rs.client.Client

这里有任何简单(甚至可能)的前进道路吗?

您可以使用 ClientRequestFilters 对 JAX-RS 客户端进行单元测试。基本上将自定义 ClientRequestFilter 注册到您的 Client 对象(或 ClientBuilder),该对象使用传递给过滤器方法的 ClientRequestContext 对象上的 abortWith(Response) 方法来模拟您的响应。

像这样的东西应该可以工作:

public MyMockRequestFilter implements ClientRequestFilter {
  @Override
  public void filter(ClientRequestContext requestContext) {
    MyEntity entity = // get the entity you want to mock as returned from the server
    requestContext.abortWith(Request.ok(entity).build());
  }
}
...
ClientBuilder builder = ClientBuilder.newBuilder().register(MyMockRequestFilter .class)

希望这对您有所帮助, 安迪