事实证明这是因为在JAVA7中,HttpURLConnection不支持PATCH,该类中支持的方法静态定义为
private static final String[] methods = {
"GET", "POST", "HEAD", "OPTIONS", "PUT", "DELETE", "TRACE"
};
但是,可以在 CXF 中发送 PATCH 请求,但 Conduit 对象必须是类型AsyncHTTPConduit
。
要使 CXF 使用 AsyncHTTPConduit,您可以像这样以编程方式实现它
AbcService service = JAXRSClientFactory.create(myURI, AbcService.class, myProviders, true);
WebClient.getConfig(service).getRequestContext().put("use.async.http.conduit", true);
service.patchEnvironmentParameters(patchRequest);
Or
WebClient client = WebClient.create("http://localhost:53261/v1-0/api/environment/parameters");
WebClient.getConfig(client).getRequestContext().put("use.async.http.conduit", true);
client.invoke("PATCH", "{}");
但要小心!为了使这项工作正常进行,您已将此依赖项放入您的项目中
<dependency>
<groupId>org.apache.cxf</groupId>
<artifactId>cxf-rt-transports-http-hc</artifactId>
<version>${cxf.version}</version>
</dependency>
还要确保您使用相同版本的cxf-rt-transports-http-hc
and cxf
.
但正如您所看到的,我所描述的内容并没有解决最初的问题,这样我就发出了 1 个特定的 PATCH 请求。然而,在我的项目中,有许多使用接口定义的 PATCH 服务,就像我最初展示的那样
public interface AbcService {
@PATCH
@Path("/abc/efg")
public SomeDTO patchSomething(RequestObject request);
}
因此,为了仅在 PATCH 方法上使用 AsyncHTTPConduit,我必须编写自定义 CXF 拦截器,您可以在此处了解更多信息http://cxf.apache.org/docs/interceptors.html http://cxf.apache.org/docs/interceptors.html我编写的拦截器在 PRE_LOGIC 阶段运行,它检查使用了哪种方法,如果它是 PATCH,它会定义管道属性。然后在服务调用的后期阶段,CXF 使用此属性来选择应使用哪个 Conduit 实现,依此类推
if ( message.get(Message.HTTP_REQUEST_METHOD).equals("PATCH") {
message.put("use.async.http.conduit", true);
}
the AsyncHTTPConduit
将使用 PATCH 起作用的实例。