Java 如何在CXF中使用PATCH方法

Java 如何在CXF中使用PATCH方法,java,rest,jax-rs,cxf,http-patch,Java,Rest,Jax Rs,Cxf,Http Patch,我试图在使用JAX-RS的CXF实现的客户机中使用补丁方法。 首先,我将面片注释定义为 @Target({ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @HttpMethod("PATCH") public @interface PATCH { } 参考此处所写内容: 然后我发现@PATCH被添加到了CXF3.1.2中,所以我在maven的pom.xml中更改了版本,实际上,包org.apache.CXF.jaxrs.ext

我试图在使用JAX-RS的CXF实现的客户机中使用补丁方法。 首先,我将面片注释定义为

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@HttpMethod("PATCH")
public @interface PATCH {
}
参考此处所写内容:

然后我发现@PATCH被添加到了CXF3.1.2中,所以我在maven的pom.xml中更改了版本,实际上,
包org.apache.CXF.jaxrs.ext中有
public@interface PATCH
并且代码实际上看起来和我上面发布的完全一样

但是,当我尝试在我的服务定义上使用此注释时

@Consumes(MediaType.APPLICATION_JSON)
@Produces(MediaType.APPLICATION_JSON)
public interface AbcService {

    @PATCH
    @Path("/abc/efg")
    public SomeDTO patchSomething(RequestObject request);
}
最后我得到了
java.net.ProtocolException:Invalid HTTP method:PATCH
,正如我在上面发布的queston链接中所说的那样。他们与Jersey讨论了一些解决方案,但是我可以在CXF中做些什么,以便使用:

AbcService abcService = JAXRSClientFactory.create(myURI, AbcService.class, myProviders, true);
abcService.patchSomething(new RequestObject('something'));
所以我有几个问题:

  • 我怎样才能做到这一点?不,我需要编写自定义CXF拦截器
  • 如果补丁注释不起作用,为什么他们要将它添加到CXF中
  • 另一个主题中的一些人说,所提到的补丁注释定义适用于他们。怎么会?它只会在客户端制造麻烦吗?如果是,为什么
  • 为什么在CXF文档中找不到此注释?我在上查看了org.apache.cxf.jaxrs.ext包,没有看到任何补丁。然而,在最新的cxf 3.1.2中,我确实可以在这个软件包中找到它

  • 您能否尝试在代码中使用
    @PATCH
    替换为
    @POST
    ,以查看它是否有效?您的
    AbcService
    接口缺少类型级别的
    @Path
    注释(除非它是子资源?),因此可能需要首先尝试使用标准HTTP谓词,以确保其他所有内容都已正确配置。

    这是因为在JAVA7中,HttpURLConnection不支持补丁,该类中受支持的方法静态定义为

       private static final String[] methods = {
            "GET", "POST", "HEAD", "OPTIONS", "PUT", "DELETE", "TRACE"
        };
    
    但是,可以在CXF中发送修补程序请求,但导管对象的类型必须为
    asynchttpconductor
    。 要使CXF使用AsynchttpConductor,您可以通过编程实现它,如下所示

    AbcService service = JAXRSClientFactory.create(myURI, AbcService.class, myProviders, true);
    WebClient.getConfig(service).getRequestContext().put("use.async.http.conduit", true);
    service.patchEnvironmentParameters(patchRequest);
    

    但是要当心!!为了实现这一点,您已经将此依赖关系放入了项目中

    <dependency>
      <groupId>org.apache.cxf</groupId>
      <artifactId>cxf-rt-transports-http-hc</artifactId>
      <version>${cxf.version}</version>
    </dependency>
    
    因此,为了仅在补丁方法上使用AsynchttpConductor,我必须编写定制的CXF拦截器,您可以在这里了解更多 我编写的拦截器在PRE_逻辑阶段运行,它检查使用哪种方法,如果它修补了,它定义了conduct属性。然后在服务调用的后期阶段,CXF使用此属性选择应该使用哪个管道实现,等等

    if ( message.get(Message.HTTP_REQUEST_METHOD).equals("PATCH") {
      message.put("use.async.http.conduit", true);
    }
    

    AsynchttpConductor
    实例将用于修补程序的工作。

    感谢您的回复,但是我们已经有很多POST和GET方法以这种方式工作,但是我们的API已经发布了一些修补程序方法。然而,现在我无法让这个java客户机与服务器通信。问题只是修补程序+CXF,其他方法都很有效。哈哈,好的。对不起,误会了。如果您可以处理较低级别的通信并在测试中使用另一种方法/API,那么您可以尝试使用HttpClient?
    public interface AbcService {
    
        @PATCH
        @Path("/abc/efg")
        public SomeDTO patchSomething(RequestObject request);
    }
    
    if ( message.get(Message.HTTP_REQUEST_METHOD).equals("PATCH") {
      message.put("use.async.http.conduit", true);
    }