如何在CXF中使用PATCH方法 [英] How to use PATCH method in CXF

查看:173
本文介绍了如何在CXF中使用PATCH方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用JAX-RS的CXF实现在客户端中使用PATCH方法. 首先,我将PATCH注释定义为

I am trying to use PATCH method in my client using CXF implementation of JAX-RS. At first I defined the PATCH annotation as

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@HttpMethod("PATCH")
public @interface PATCH {
}

参考此处的内容: 如何为JAX-RS使用@PATCH注释?

然后我发现@PATCH已添加到CXF 3.1.2中,因此我在maven的pom.xml中更改了版本,并且package org.apache.cxf.jaxrs.ext;内确实存在public @interface PATCH,并且代码实际上与我上面发布的内容完全相同

Then I found out @PATCH was added into CXF 3.1.2, so I changed version in my maven's pom.xml and indeed there is public @interface PATCH inside of package org.apache.cxf.jaxrs.ext; and the code actually looks exactly as what I posted above.

但是,当我尝试在服务定义上将此注释用作

However, when I try to use this annotation on my service definition as

@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,就像我上面发布的问题链接中所说的那样.他们与Jersey讨论了一些解决方案,但是我可以在CXF中做些什么,以便可以使用:

I end up with the java.net.ProtocolException: Invalid HTTP method: PATCH as was said in the queston link I posted above. They discuss some solution for this with Jersey, however what I can I do in CXF, so that I can use :

AbcService abcService = JAXRSClientFactory.create(myURI, AbcService.class, myProviders, true);
abcService.patchSomething(new RequestObject('something'));

所以我有几个问题:

  1. 我该如何进行这项工作?不,我需要编写自定义CXF拦截器?
  2. 为什么他们不将PATCH注释添加到CXF中?
  3. 另一个主题中的一些人说,提到的PATCH注释定义适用于他们.怎么会 ?它只会在客户端造成麻烦吗?如果是这样,为什么呢?
  4. 为什么在CXF文档中找不到此注释?我在 http://cxf.apache.org上查看了org.apache.cxf.jaxrs.ext包. /javadoc/latest/,但看不到任何补丁.但是在最新的cxf 3.1.2中,我确实可以在此软件包中找到它.
  1. How can I make this work ? No I need to write custom CXF interceptor ?
  2. Why did they add the PATCH annotation into CXF if it doesn't work ?
  3. Some guys in the other topic said that the mentioned PATCH annotation definition works for them. How come ? Does it only make trouble on the client side, and if so why is it ?
  4. Why I can't find this annotation in CXF documentation ? I looked into org.apache.cxf.jaxrs.ext package at http://cxf.apache.org/javadoc/latest/ and I don't see any PATCH. Yet in the latest cxf 3.1.2 I really can find it in this package.

推荐答案

事实证明是有原因的,因为在JAVA7中,HttpURLConnection不支持PATCH,该类中受支持的方法静态定义为

It turns out it's cause because in JAVA7, HttpURLConnection doesn't support PATCH, the supported methods in that class are defined statically as

   private static final String[] methods = {
        "GET", "POST", "HEAD", "OPTIONS", "PUT", "DELETE", "TRACE"
    };

但是可以在CXF中发送PATCH请求,但是Conduit对象的类型必须为AsyncHTTPConduit. 要使CXF使用AsyncHTTPConduit,您可以通过编程方式实现此目的

However it is possible to send PATCH request in CXF, but the Conduit object must be of type AsyncHTTPConduit. To make CXF use AsyncHTTPConduit, you can programatically achieve it like this

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

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", "{}");

但是要当心!!为了使这项工作有效,您已将此依赖项放入您的项目中

But beware !! In order to make this work, you have put this dependency into your project

<dependency>
  <groupId>org.apache.cxf</groupId>
  <artifactId>cxf-rt-transports-http-hc</artifactId>
  <version>${cxf.version}</version>
</dependency>

还要确保使用相同版本的cxf-rt-transports-http-hccxf.

Also make sure that you use the same version of cxf-rt-transports-http-hc and cxf.

但是正如您所看到的,我所描述的并不能解决原始问题,因此,我只发出了1个特定的PATCH请求.但是在我的项目中,有许多使用我最初显示的接口定义的PATCH服务

But as you can see what I described doesn't solve the original issue, this way I just made 1 specific PATCH request. However in my project there are many PATCH services defined using interfaces like I showed originally

public interface AbcService {

    @PATCH
    @Path("/abc/efg")
    public SomeDTO patchSomething(RequestObject request);
}

因此,为了仅在PATCH方法上使用AsyncHTTPConduit,我必须编写自定义CXF拦截器,您可以在此处了解更多信息

So in order to use the AsyncHTTPConduit only on PATCH methods, I had to write custom CXF interceptor, about which you can learn more here http://cxf.apache.org/docs/interceptors.html The interceptor I wrote runs in PRE_LOGIC phase and it checks what kind of method is used and in case it PATCH, it defined the conduit property. Then in latter phases of service invocation, CXF uses this property to choose which Conduit implementation should be used, and so after

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

AsyncHTTPConduit实例将与PATCH一起使用.

the AsyncHTTPConduit instance will be used with which the PATCH will work.

这篇关于如何在CXF中使用PATCH方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆