5.5. Client Transport Connectors 客户端传输连接器

默认的,Jersey 传输层提供了 HttpUrlConnection。这个转换是通过实现了 Connector SPI 接口的HttpUrlConnectorProvider 实现的。你可以执行和/或注册自己的 Connector 实例到 Jersey 客户端的实现,这将取代 基于 默认HttpURLConnection 的传输层。

Jersey 提供了几种可供选择的客户端传输连接器的实现。可以使用 ApacheConnectorProvider(添加 maven 依赖 org.glassfish.jersey.connectors:jersey-apache-connector) 或 GrizzlyConnectorProvider (添加 maven 依赖org.glassfish.jersey.connectors:jersey-grizzly-connector) 或 JettyConnectorProvider (添加 maven 依赖 org.glassfish.jersey.connectors:jersey-jetty-connector)

警告

小心使用除默认 Connector 外的其他实现。在处理 WriterInterceptor 或 MessageBodyWriter 的 HTTP 头文件时 有一个问题。 如果需要修改头文件字段,当使用ApacheConnectorProvider 、 GrizzlyConnectorProvider 或者 JettyConnectorProvider 的时候。例如,应用于Multipart功能时,也要修改 HTTP 头文件

另一方面,在默认的传输连接,对头文件有一些限制,可以在默认配置发送。HttpUrlConnectorProvider 使用 HttpUrlConnection 作为一个基本的连接实现。这 JDK 类默认限制使用以下头文件:

  • Access-Control-Request-Headers
  • Access-Control-Request-Method
  • Connection (有一个例外-默认情况下允许 Connection 头文件的值为 Closed)
  • Content-Length
  • Content-Transfer-Encoding-
  • Host
  • Keep-Alive
  • Origin
  • Trailer
  • Transfer-Encoding
  • Upgrade
  • Via
  • 所有以 Sec- 开头的头文件

基础连接可以被配置为允许发送所有的头文件,但是这种行为只可以通过设置系统属性 sun.net.http.allowRestrictedHeaders 改变。

Example 5.4. Sending restricted headers with HttpUrlConnector

  1. Client client = ClientBuilder.newClient();
  2. System.setProperty("sun.net.http.allowRestrictedHeaders", "true");
  3. Response response = client.target(yourUri).path(yourPath).request().
  4. header("Origin", "http://example.com").
  5. header("Access-Control-Request-Method", "POST").
  6. get();

注意,在内部 HttpUrlConnection 实例是公用的,所以(不)设置属性后,已创建一个目标通常不会有任何影响。这个属性影响所有在属性被(不)设置之后的连接器,但这没有保证,您的请求将使用当属性更改后创建的一个连接器。

在一个简单的环境,在创建第一个目标之前设置属性是可以胜任的。但在复杂的环境(如应用服务器),其中一些可以共享的连接器可能在你的应用程序引导之前就存在了,这种方法是不可靠的,我们建议使用不同的客户端传输连接器,如 Apache Connector。这些限制必须被考虑,当在调用 CORS(Cross Origin Resource Sharing 跨域资源共享)的请求时。

如前所述,Connector 和 ConnectorProvider 都是 Jersey 特定扩展API,只能用在 Jersey,并不属于 JAX-RS。下面的例子显示了如何在一个 Jersey 客户端基于 ConnectorProvider 实例的 Grizzly Asynchronous HTTP Client:

  1. ClientConfig clientConfig = new ClientConfig();
  2. clientConfig.connectorProvider(new GrizzlyConnectorProvider());
  3. Client client = ClientBuilder.newClient(clientConfig);

客户接受作为构造函数参数的 Configurable 实例。Configurable 实现的提供者为客户提供 ClientConfig。通过使用 Jersey ClientConfig可以配置自定义 ConnectorProvider 到 ClientConfig。该GrizzlyConnectorProvider 作为自定义连接器供应者在上面的例子中。请注意,该连接器供应者不能被注册为一个供应商使用 Configurable.register(…)。另外,请注意在这个 API 在 Jersey 2.5 的变化,ConnectorProvider SPI 已经推出了以客户端初始化从连接器实例化解耦。从 Jersey 2.5 开始,因此不可能直接在 Jersey ClientConfig 注册 Connector 实例。新的 ConnectorProvider SPI 必须代替配置一个自定义客户端传输连接器。